Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
[safe/jmp/linux-2.6] / fs / xfs / xfs_bmap.c
index 47a87de..98251cd 100644 (file)
@@ -54,6 +54,7 @@
 #include "xfs_buf_item.h"
 #include "xfs_filestream.h"
 #include "xfs_vnodeops.h"
+#include "xfs_trace.h"
 
 
 #ifdef DEBUG
@@ -272,71 +273,6 @@ xfs_bmap_isaeof(
        int             whichfork,      /* data or attribute fork */
        char            *aeof);         /* return value */
 
-#ifdef XFS_BMAP_TRACE
-/*
- * Add bmap trace entry prior to a call to xfs_iext_remove.
- */
-STATIC void
-xfs_bmap_trace_delete(
-       const char      *fname,         /* function name */
-       char            *desc,          /* operation description */
-       xfs_inode_t     *ip,            /* incore inode pointer */
-       xfs_extnum_t    idx,            /* index of entry(entries) deleted */
-       xfs_extnum_t    cnt,            /* count of entries deleted, 1 or 2 */
-       int             whichfork);     /* data or attr fork */
-
-/*
- * Add bmap trace entry prior to a call to xfs_iext_insert, or
- * reading in the extents list from the disk (in the btree).
- */
-STATIC void
-xfs_bmap_trace_insert(
-       const char      *fname,         /* function name */
-       char            *desc,          /* operation description */
-       xfs_inode_t     *ip,            /* incore inode pointer */
-       xfs_extnum_t    idx,            /* index of entry(entries) inserted */
-       xfs_extnum_t    cnt,            /* count of entries inserted, 1 or 2 */
-       xfs_bmbt_irec_t *r1,            /* inserted record 1 */
-       xfs_bmbt_irec_t *r2,            /* inserted record 2 or null */
-       int             whichfork);     /* data or attr fork */
-
-/*
- * Add bmap trace entry after updating an extent record in place.
- */
-STATIC void
-xfs_bmap_trace_post_update(
-       const char      *fname,         /* function name */
-       char            *desc,          /* operation description */
-       xfs_inode_t     *ip,            /* incore inode pointer */
-       xfs_extnum_t    idx,            /* index of entry updated */
-       int             whichfork);     /* data or attr fork */
-
-/*
- * Add bmap trace entry prior to updating an extent record in place.
- */
-STATIC void
-xfs_bmap_trace_pre_update(
-       const char      *fname,         /* function name */
-       char            *desc,          /* operation description */
-       xfs_inode_t     *ip,            /* incore inode pointer */
-       xfs_extnum_t    idx,            /* index of entry to be updated */
-       int             whichfork);     /* data or attr fork */
-
-#define        XFS_BMAP_TRACE_DELETE(d,ip,i,c,w)       \
-       xfs_bmap_trace_delete(__func__,d,ip,i,c,w)
-#define        XFS_BMAP_TRACE_INSERT(d,ip,i,c,r1,r2,w) \
-       xfs_bmap_trace_insert(__func__,d,ip,i,c,r1,r2,w)
-#define        XFS_BMAP_TRACE_POST_UPDATE(d,ip,i,w)    \
-       xfs_bmap_trace_post_update(__func__,d,ip,i,w)
-#define        XFS_BMAP_TRACE_PRE_UPDATE(d,ip,i,w)     \
-       xfs_bmap_trace_pre_update(__func__,d,ip,i,w)
-#else
-#define        XFS_BMAP_TRACE_DELETE(d,ip,i,c,w)
-#define        XFS_BMAP_TRACE_INSERT(d,ip,i,c,r1,r2,w)
-#define        XFS_BMAP_TRACE_POST_UPDATE(d,ip,i,w)
-#define        XFS_BMAP_TRACE_PRE_UPDATE(d,ip,i,w)
-#endif /* XFS_BMAP_TRACE */
-
 /*
  * Compute the worst-case number of indirect blocks that will be used
  * for ip's delayed extent of length "len".
@@ -363,18 +299,6 @@ xfs_bmap_validate_ret(
 #define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
 #endif /* DEBUG */
 
-#if defined(XFS_RW_TRACE)
-STATIC void
-xfs_bunmap_trace(
-       xfs_inode_t             *ip,
-       xfs_fileoff_t           bno,
-       xfs_filblks_t           len,
-       int                     flags,
-       inst_t                  *ra);
-#else
-#define        xfs_bunmap_trace(ip, bno, len, flags, ra)
-#endif /* XFS_RW_TRACE */
-
 STATIC int
 xfs_bmap_count_tree(
        xfs_mount_t     *mp,
@@ -590,9 +514,9 @@ xfs_bmap_add_extent(
         * already extents in the list.
         */
        if (nextents == 0) {
-               XFS_BMAP_TRACE_INSERT("insert empty", ip, 0, 1, new, NULL,
-                       whichfork);
-               xfs_iext_insert(ifp, 0, 1, new);
+               xfs_iext_insert(ip, 0, 1, new,
+                               whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0);
+
                ASSERT(cur == NULL);
                ifp->if_lastex = 0;
                if (!isnullstartblock(new->br_startblock)) {
@@ -759,26 +683,10 @@ xfs_bmap_add_extent_delay_real(
        xfs_filblks_t           temp=0; /* value for dnew calculations */
        xfs_filblks_t           temp2=0;/* value for dnew calculations */
        int                     tmp_rval;       /* partial logging flags */
-       enum {                          /* bit number definitions for state */
-               LEFT_CONTIG,    RIGHT_CONTIG,
-               LEFT_FILLING,   RIGHT_FILLING,
-               LEFT_DELAY,     RIGHT_DELAY,
-               LEFT_VALID,     RIGHT_VALID
-       };
 
 #define        LEFT            r[0]
 #define        RIGHT           r[1]
 #define        PREV            r[2]
-#define        MASK(b)         (1 << (b))
-#define        MASK2(a,b)      (MASK(a) | MASK(b))
-#define        MASK3(a,b,c)    (MASK2(a,b) | MASK(c))
-#define        MASK4(a,b,c,d)  (MASK3(a,b,c) | MASK(d))
-#define        STATE_SET(b,v)  ((v) ? (state |= MASK(b)) : (state &= ~MASK(b)))
-#define        STATE_TEST(b)   (state & MASK(b))
-#define        STATE_SET_TEST(b,v)     ((v) ? ((state |= MASK(b)), 1) : \
-                                      ((state &= ~MASK(b)), 0))
-#define        SWITCH_STATE            \
-       (state & MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG))
 
        /*
         * Set up a bunch of variables to make the tests simpler.
@@ -790,69 +698,80 @@ xfs_bmap_add_extent_delay_real(
        new_endoff = new->br_startoff + new->br_blockcount;
        ASSERT(PREV.br_startoff <= new->br_startoff);
        ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff);
+
        /*
         * Set flags determining what part of the previous delayed allocation
         * extent is being replaced by a real allocation.
         */
-       STATE_SET(LEFT_FILLING, PREV.br_startoff == new->br_startoff);
-       STATE_SET(RIGHT_FILLING,
-               PREV.br_startoff + PREV.br_blockcount == new_endoff);
+       if (PREV.br_startoff == new->br_startoff)
+               state |= BMAP_LEFT_FILLING;
+       if (PREV.br_startoff + PREV.br_blockcount == new_endoff)
+               state |= BMAP_RIGHT_FILLING;
+
        /*
         * Check and set flags if this segment has a left neighbor.
         * Don't set contiguous if the combined extent would be too large.
         */
-       if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
+       if (idx > 0) {
+               state |= BMAP_LEFT_VALID;
                xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT);
-               STATE_SET(LEFT_DELAY, isnullstartblock(LEFT.br_startblock));
+
+               if (isnullstartblock(LEFT.br_startblock))
+                       state |= BMAP_LEFT_DELAY;
        }
-       STATE_SET(LEFT_CONTIG,
-               STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) &&
-               LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
-               LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
-               LEFT.br_state == new->br_state &&
-               LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN);
+
+       if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) &&
+           LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
+           LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
+           LEFT.br_state == new->br_state &&
+           LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+               state |= BMAP_LEFT_CONTIG;
+
        /*
         * Check and set flags if this segment has a right neighbor.
         * Don't set contiguous if the combined extent would be too large.
         * Also check for all-three-contiguous being too large.
         */
-       if (STATE_SET_TEST(RIGHT_VALID,
-                       idx <
-                       ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) {
+       if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
+               state |= BMAP_RIGHT_VALID;
                xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT);
-               STATE_SET(RIGHT_DELAY, isnullstartblock(RIGHT.br_startblock));
+
+               if (isnullstartblock(RIGHT.br_startblock))
+                       state |= BMAP_RIGHT_DELAY;
        }
-       STATE_SET(RIGHT_CONTIG,
-               STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) &&
-               new_endoff == RIGHT.br_startoff &&
-               new->br_startblock + new->br_blockcount ==
-                   RIGHT.br_startblock &&
-               new->br_state == RIGHT.br_state &&
-               new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
-               ((state & MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING)) !=
-                 MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING) ||
-                LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
-                    <= MAXEXTLEN));
+
+       if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
+           new_endoff == RIGHT.br_startoff &&
+           new->br_startblock + new->br_blockcount == RIGHT.br_startblock &&
+           new->br_state == RIGHT.br_state &&
+           new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
+           ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
+                      BMAP_RIGHT_FILLING)) !=
+                     (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
+                      BMAP_RIGHT_FILLING) ||
+            LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
+                       <= MAXEXTLEN))
+               state |= BMAP_RIGHT_CONTIG;
+
        error = 0;
        /*
         * Switch out based on the FILLING and CONTIG state bits.
         */
-       switch (SWITCH_STATE) {
-
-       case MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
+       switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
+                        BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) {
+       case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
+            BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
                /*
                 * Filling in all of a previously delayed allocation extent.
                 * The left and right neighbors are both contiguous with new.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC|RC", ip, idx - 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
                        LEFT.br_blockcount + PREV.br_blockcount +
                        RIGHT.br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC|RC", ip, idx - 1,
-                       XFS_DATA_FORK);
-               XFS_BMAP_TRACE_DELETE("LF|RF|LC|RC", ip, idx, 2, XFS_DATA_FORK);
-               xfs_iext_remove(ifp, idx, 2);
+               trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
+
+               xfs_iext_remove(ip, idx, 2, state);
                ip->i_df.if_lastex = idx - 1;
                ip->i_d.di_nextents--;
                if (cur == NULL)
@@ -885,20 +804,18 @@ xfs_bmap_add_extent_delay_real(
                        RIGHT.br_blockcount;
                break;
 
-       case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
+       case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
                /*
                 * Filling in all of a previously delayed allocation extent.
                 * The left neighbor is contiguous, the right is not.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC", ip, idx - 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
                        LEFT.br_blockcount + PREV.br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC", ip, idx - 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
+
                ip->i_df.if_lastex = idx - 1;
-               XFS_BMAP_TRACE_DELETE("LF|RF|LC", ip, idx, 1, XFS_DATA_FORK);
-               xfs_iext_remove(ifp, idx, 1);
+               xfs_iext_remove(ip, idx, 1, state);
                if (cur == NULL)
                        rval = XFS_ILOG_DEXT;
                else {
@@ -921,19 +838,19 @@ xfs_bmap_add_extent_delay_real(
                        PREV.br_blockcount;
                break;
 
-       case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
+       case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
                /*
                 * Filling in all of a previously delayed allocation extent.
                 * The right neighbor is contiguous, the left is not.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_startblock(ep, new->br_startblock);
                xfs_bmbt_set_blockcount(ep,
                        PREV.br_blockcount + RIGHT.br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+
                ip->i_df.if_lastex = idx;
-               XFS_BMAP_TRACE_DELETE("LF|RF|RC", ip, idx + 1, 1, XFS_DATA_FORK);
-               xfs_iext_remove(ifp, idx + 1, 1);
+               xfs_iext_remove(ip, idx + 1, 1, state);
                if (cur == NULL)
                        rval = XFS_ILOG_DEXT;
                else {
@@ -956,15 +873,16 @@ xfs_bmap_add_extent_delay_real(
                        RIGHT.br_blockcount;
                break;
 
-       case MASK2(LEFT_FILLING, RIGHT_FILLING):
+       case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
                /*
                 * Filling in all of a previously delayed allocation extent.
                 * Neither the left nor right neighbors are contiguous with
                 * the new one.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|RF", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_startblock(ep, new->br_startblock);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|RF", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+
                ip->i_df.if_lastex = idx;
                ip->i_d.di_nextents++;
                if (cur == NULL)
@@ -987,19 +905,20 @@ xfs_bmap_add_extent_delay_real(
                temp2 = new->br_blockcount;
                break;
 
-       case MASK2(LEFT_FILLING, LEFT_CONTIG):
+       case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG:
                /*
                 * Filling in the first part of a previous delayed allocation.
                 * The left neighbor is contiguous.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx - 1, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
                        LEFT.br_blockcount + new->br_blockcount);
                xfs_bmbt_set_startoff(ep,
                        PREV.br_startoff + new->br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx - 1, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
+
                temp = PREV.br_blockcount - new->br_blockcount;
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(ep, temp);
                ip->i_df.if_lastex = idx - 1;
                if (cur == NULL)
@@ -1021,7 +940,7 @@ xfs_bmap_add_extent_delay_real(
                temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
                        startblockval(PREV.br_startblock));
                xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
-               XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
                *dnew = temp;
                /* DELTA: The boundary between two in-core extents moved. */
                temp = LEFT.br_startoff;
@@ -1029,18 +948,16 @@ xfs_bmap_add_extent_delay_real(
                        PREV.br_blockcount;
                break;
 
-       case MASK(LEFT_FILLING):
+       case BMAP_LEFT_FILLING:
                /*
                 * Filling in the first part of a previous delayed allocation.
                 * The left neighbor is not contiguous.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_startoff(ep, new_endoff);
                temp = PREV.br_blockcount - new->br_blockcount;
                xfs_bmbt_set_blockcount(ep, temp);
-               XFS_BMAP_TRACE_INSERT("LF", ip, idx, 1, new, NULL,
-                       XFS_DATA_FORK);
-               xfs_iext_insert(ifp, idx, 1, new);
+               xfs_iext_insert(ip, idx, 1, new, state);
                ip->i_df.if_lastex = idx;
                ip->i_d.di_nextents++;
                if (cur == NULL)
@@ -1071,27 +988,27 @@ xfs_bmap_add_extent_delay_real(
                        (cur ? cur->bc_private.b.allocated : 0));
                ep = xfs_iext_get_ext(ifp, idx + 1);
                xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
-               XFS_BMAP_TRACE_POST_UPDATE("LF", ip, idx + 1, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_);
                *dnew = temp;
                /* DELTA: One in-core extent is split in two. */
                temp = PREV.br_startoff;
                temp2 = PREV.br_blockcount;
                break;
 
-       case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
+       case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
                /*
                 * Filling in the last part of a previous delayed allocation.
                 * The right neighbor is contiguous with the new allocation.
                 */
                temp = PREV.br_blockcount - new->br_blockcount;
-               XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK);
-               XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx + 1, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
+               trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(ep, temp);
                xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1),
                        new->br_startoff, new->br_startblock,
                        new->br_blockcount + RIGHT.br_blockcount,
                        RIGHT.br_state);
-               XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx + 1, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_);
                ip->i_df.if_lastex = idx + 1;
                if (cur == NULL)
                        rval = XFS_ILOG_DEXT;
@@ -1112,7 +1029,7 @@ xfs_bmap_add_extent_delay_real(
                temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
                        startblockval(PREV.br_startblock));
                xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
-               XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
                *dnew = temp;
                /* DELTA: The boundary between two in-core extents moved. */
                temp = PREV.br_startoff;
@@ -1120,17 +1037,15 @@ xfs_bmap_add_extent_delay_real(
                        RIGHT.br_blockcount;
                break;
 
-       case MASK(RIGHT_FILLING):
+       case BMAP_RIGHT_FILLING:
                /*
                 * Filling in the last part of a previous delayed allocation.
                 * The right neighbor is not contiguous.
                 */
                temp = PREV.br_blockcount - new->br_blockcount;
-               XFS_BMAP_TRACE_PRE_UPDATE("RF", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(ep, temp);
-               XFS_BMAP_TRACE_INSERT("RF", ip, idx + 1, 1, new, NULL,
-                       XFS_DATA_FORK);
-               xfs_iext_insert(ifp, idx + 1, 1, new);
+               xfs_iext_insert(ip, idx + 1, 1, new, state);
                ip->i_df.if_lastex = idx + 1;
                ip->i_d.di_nextents++;
                if (cur == NULL)
@@ -1161,7 +1076,7 @@ xfs_bmap_add_extent_delay_real(
                        (cur ? cur->bc_private.b.allocated : 0));
                ep = xfs_iext_get_ext(ifp, idx);
                xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
-               XFS_BMAP_TRACE_POST_UPDATE("RF", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
                *dnew = temp;
                /* DELTA: One in-core extent is split in two. */
                temp = PREV.br_startoff;
@@ -1175,7 +1090,7 @@ xfs_bmap_add_extent_delay_real(
                 * This case is avoided almost all the time.
                 */
                temp = new->br_startoff - PREV.br_startoff;
-               XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_);
                xfs_bmbt_set_blockcount(ep, temp);
                r[0] = *new;
                r[1].br_state = PREV.br_state;
@@ -1183,9 +1098,7 @@ xfs_bmap_add_extent_delay_real(
                r[1].br_startoff = new_endoff;
                temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
                r[1].br_blockcount = temp2;
-               XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 2, &r[0], &r[1],
-                       XFS_DATA_FORK);
-               xfs_iext_insert(ifp, idx + 1, 2, &r[0]);
+               xfs_iext_insert(ip, idx + 1, 2, &r[0], state);
                ip->i_df.if_lastex = idx + 1;
                ip->i_d.di_nextents++;
                if (cur == NULL)
@@ -1242,24 +1155,24 @@ xfs_bmap_add_extent_delay_real(
                }
                ep = xfs_iext_get_ext(ifp, idx);
                xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
-               XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, XFS_DATA_FORK);
-               XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx + 2, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+               trace_xfs_bmap_pre_update(ip, idx + 2, state, _THIS_IP_);
                xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2),
                        nullstartblock((int)temp2));
-               XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx + 2, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx + 2, state, _THIS_IP_);
                *dnew = temp + temp2;
                /* DELTA: One in-core extent is split in three. */
                temp = PREV.br_startoff;
                temp2 = PREV.br_blockcount;
                break;
 
-       case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
-       case MASK3(RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
-       case MASK2(LEFT_FILLING, RIGHT_CONTIG):
-       case MASK2(RIGHT_FILLING, LEFT_CONTIG):
-       case MASK2(LEFT_CONTIG, RIGHT_CONTIG):
-       case MASK(LEFT_CONTIG):
-       case MASK(RIGHT_CONTIG):
+       case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
+       case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
+       case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG:
+       case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
+       case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
+       case BMAP_LEFT_CONTIG:
+       case BMAP_RIGHT_CONTIG:
                /*
                 * These cases are all impossible.
                 */
@@ -1279,14 +1192,6 @@ done:
 #undef LEFT
 #undef RIGHT
 #undef PREV
-#undef MASK
-#undef MASK2
-#undef MASK3
-#undef MASK4
-#undef STATE_SET
-#undef STATE_TEST
-#undef STATE_SET_TEST
-#undef SWITCH_STATE
 }
 
 /*
@@ -1316,27 +1221,10 @@ xfs_bmap_add_extent_unwritten_real(
        int                     state = 0;/* state bits, accessed thru macros */
        xfs_filblks_t           temp=0;
        xfs_filblks_t           temp2=0;
-       enum {                          /* bit number definitions for state */
-               LEFT_CONTIG,    RIGHT_CONTIG,
-               LEFT_FILLING,   RIGHT_FILLING,
-               LEFT_DELAY,     RIGHT_DELAY,
-               LEFT_VALID,     RIGHT_VALID
-       };
 
 #define        LEFT            r[0]
 #define        RIGHT           r[1]
 #define        PREV            r[2]
-#define        MASK(b)         (1 << (b))
-#define        MASK2(a,b)      (MASK(a) | MASK(b))
-#define        MASK3(a,b,c)    (MASK2(a,b) | MASK(c))
-#define        MASK4(a,b,c,d)  (MASK3(a,b,c) | MASK(d))
-#define        STATE_SET(b,v)  ((v) ? (state |= MASK(b)) : (state &= ~MASK(b)))
-#define        STATE_TEST(b)   (state & MASK(b))
-#define        STATE_SET_TEST(b,v)     ((v) ? ((state |= MASK(b)), 1) : \
-                                      ((state &= ~MASK(b)), 0))
-#define        SWITCH_STATE            \
-       (state & MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG))
-
        /*
         * Set up a bunch of variables to make the tests simpler.
         */
@@ -1352,68 +1240,78 @@ xfs_bmap_add_extent_unwritten_real(
        new_endoff = new->br_startoff + new->br_blockcount;
        ASSERT(PREV.br_startoff <= new->br_startoff);
        ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff);
+
        /*
         * Set flags determining what part of the previous oldext allocation
         * extent is being replaced by a newext allocation.
         */
-       STATE_SET(LEFT_FILLING, PREV.br_startoff == new->br_startoff);
-       STATE_SET(RIGHT_FILLING,
-               PREV.br_startoff + PREV.br_blockcount == new_endoff);
+       if (PREV.br_startoff == new->br_startoff)
+               state |= BMAP_LEFT_FILLING;
+       if (PREV.br_startoff + PREV.br_blockcount == new_endoff)
+               state |= BMAP_RIGHT_FILLING;
+
        /*
         * Check and set flags if this segment has a left neighbor.
         * Don't set contiguous if the combined extent would be too large.
         */
-       if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
+       if (idx > 0) {
+               state |= BMAP_LEFT_VALID;
                xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT);
-               STATE_SET(LEFT_DELAY, isnullstartblock(LEFT.br_startblock));
+
+               if (isnullstartblock(LEFT.br_startblock))
+                       state |= BMAP_LEFT_DELAY;
        }
-       STATE_SET(LEFT_CONTIG,
-               STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) &&
-               LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
-               LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
-               LEFT.br_state == newext &&
-               LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN);
+
+       if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) &&
+           LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
+           LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
+           LEFT.br_state == newext &&
+           LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+               state |= BMAP_LEFT_CONTIG;
+
        /*
         * Check and set flags if this segment has a right neighbor.
         * Don't set contiguous if the combined extent would be too large.
         * Also check for all-three-contiguous being too large.
         */
-       if (STATE_SET_TEST(RIGHT_VALID,
-                       idx <
-                       ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) {
+       if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
+               state |= BMAP_RIGHT_VALID;
                xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT);
-               STATE_SET(RIGHT_DELAY, isnullstartblock(RIGHT.br_startblock));
+               if (isnullstartblock(RIGHT.br_startblock))
+                       state |= BMAP_RIGHT_DELAY;
        }
-       STATE_SET(RIGHT_CONTIG,
-               STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) &&
-               new_endoff == RIGHT.br_startoff &&
-               new->br_startblock + new->br_blockcount ==
-                   RIGHT.br_startblock &&
-               newext == RIGHT.br_state &&
-               new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
-               ((state & MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING)) !=
-                 MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING) ||
-                LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
-                    <= MAXEXTLEN));
+
+       if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
+           new_endoff == RIGHT.br_startoff &&
+           new->br_startblock + new->br_blockcount == RIGHT.br_startblock &&
+           newext == RIGHT.br_state &&
+           new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
+           ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
+                      BMAP_RIGHT_FILLING)) !=
+                     (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
+                      BMAP_RIGHT_FILLING) ||
+            LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
+                       <= MAXEXTLEN))
+               state |= BMAP_RIGHT_CONTIG;
+
        /*
         * Switch out based on the FILLING and CONTIG state bits.
         */
-       switch (SWITCH_STATE) {
-
-       case MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
+       switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
+                        BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) {
+       case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
+            BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
                /*
                 * Setting all of a previous oldext extent to newext.
                 * The left and right neighbors are both contiguous with new.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC|RC", ip, idx - 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
                        LEFT.br_blockcount + PREV.br_blockcount +
                        RIGHT.br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC|RC", ip, idx - 1,
-                       XFS_DATA_FORK);
-               XFS_BMAP_TRACE_DELETE("LF|RF|LC|RC", ip, idx, 2, XFS_DATA_FORK);
-               xfs_iext_remove(ifp, idx, 2);
+               trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
+
+               xfs_iext_remove(ip, idx, 2, state);
                ip->i_df.if_lastex = idx - 1;
                ip->i_d.di_nextents -= 2;
                if (cur == NULL)
@@ -1450,20 +1348,18 @@ xfs_bmap_add_extent_unwritten_real(
                        RIGHT.br_blockcount;
                break;
 
-       case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
+       case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
                /*
                 * Setting all of a previous oldext extent to newext.
                 * The left neighbor is contiguous, the right is not.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC", ip, idx - 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
                        LEFT.br_blockcount + PREV.br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC", ip, idx - 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
+
                ip->i_df.if_lastex = idx - 1;
-               XFS_BMAP_TRACE_DELETE("LF|RF|LC", ip, idx, 1, XFS_DATA_FORK);
-               xfs_iext_remove(ifp, idx, 1);
+               xfs_iext_remove(ip, idx, 1, state);
                ip->i_d.di_nextents--;
                if (cur == NULL)
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1492,21 +1388,18 @@ xfs_bmap_add_extent_unwritten_real(
                        PREV.br_blockcount;
                break;
 
-       case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
+       case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
                /*
                 * Setting all of a previous oldext extent to newext.
                 * The right neighbor is contiguous, the left is not.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|RC", ip, idx,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(ep,
                        PREV.br_blockcount + RIGHT.br_blockcount);
                xfs_bmbt_set_state(ep, newext);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|RF|RC", ip, idx,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
                ip->i_df.if_lastex = idx;
-               XFS_BMAP_TRACE_DELETE("LF|RF|RC", ip, idx + 1, 1, XFS_DATA_FORK);
-               xfs_iext_remove(ifp, idx + 1, 1);
+               xfs_iext_remove(ip, idx + 1, 1, state);
                ip->i_d.di_nextents--;
                if (cur == NULL)
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1535,17 +1428,16 @@ xfs_bmap_add_extent_unwritten_real(
                        RIGHT.br_blockcount;
                break;
 
-       case MASK2(LEFT_FILLING, RIGHT_FILLING):
+       case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
                /*
                 * Setting all of a previous oldext extent to newext.
                 * Neither the left nor right neighbors are contiguous with
                 * the new one.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|RF", ip, idx,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_state(ep, newext);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|RF", ip, idx,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+
                ip->i_df.if_lastex = idx;
                if (cur == NULL)
                        rval = XFS_ILOG_DEXT;
@@ -1566,27 +1458,25 @@ xfs_bmap_add_extent_unwritten_real(
                temp2 = new->br_blockcount;
                break;
 
-       case MASK2(LEFT_FILLING, LEFT_CONTIG):
+       case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG:
                /*
                 * Setting the first part of a previous oldext extent to newext.
                 * The left neighbor is contiguous.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx - 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
                        LEFT.br_blockcount + new->br_blockcount);
                xfs_bmbt_set_startoff(ep,
                        PREV.br_startoff + new->br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx - 1,
-                       XFS_DATA_FORK);
-               XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
+
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_startblock(ep,
                        new->br_startblock + new->br_blockcount);
                xfs_bmbt_set_blockcount(ep,
                        PREV.br_blockcount - new->br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+
                ip->i_df.if_lastex = idx - 1;
                if (cur == NULL)
                        rval = XFS_ILOG_DEXT;
@@ -1617,22 +1507,21 @@ xfs_bmap_add_extent_unwritten_real(
                        PREV.br_blockcount;
                break;
 
-       case MASK(LEFT_FILLING):
+       case BMAP_LEFT_FILLING:
                /*
                 * Setting the first part of a previous oldext extent to newext.
                 * The left neighbor is not contiguous.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LF", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                ASSERT(ep && xfs_bmbt_get_state(ep) == oldext);
                xfs_bmbt_set_startoff(ep, new_endoff);
                xfs_bmbt_set_blockcount(ep,
                        PREV.br_blockcount - new->br_blockcount);
                xfs_bmbt_set_startblock(ep,
                        new->br_startblock + new->br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LF", ip, idx, XFS_DATA_FORK);
-               XFS_BMAP_TRACE_INSERT("LF", ip, idx, 1, new, NULL,
-                       XFS_DATA_FORK);
-               xfs_iext_insert(ifp, idx, 1, new);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+
+               xfs_iext_insert(ip, idx, 1, new, state);
                ip->i_df.if_lastex = idx;
                ip->i_d.di_nextents++;
                if (cur == NULL)
@@ -1660,24 +1549,21 @@ xfs_bmap_add_extent_unwritten_real(
                temp2 = PREV.br_blockcount;
                break;
 
-       case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
+       case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
                /*
                 * Setting the last part of a previous oldext extent to newext.
                 * The right neighbor is contiguous with the new allocation.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx,
-                       XFS_DATA_FORK);
-               XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx + 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
+               trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(ep,
                        PREV.br_blockcount - new->br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1),
                        new->br_startoff, new->br_startblock,
                        new->br_blockcount + RIGHT.br_blockcount, newext);
-               XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx + 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_);
+
                ip->i_df.if_lastex = idx + 1;
                if (cur == NULL)
                        rval = XFS_ILOG_DEXT;
@@ -1707,18 +1593,17 @@ xfs_bmap_add_extent_unwritten_real(
                        RIGHT.br_blockcount;
                break;
 
-       case MASK(RIGHT_FILLING):
+       case BMAP_RIGHT_FILLING:
                /*
                 * Setting the last part of a previous oldext extent to newext.
                 * The right neighbor is not contiguous.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("RF", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(ep,
                        PREV.br_blockcount - new->br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("RF", ip, idx, XFS_DATA_FORK);
-               XFS_BMAP_TRACE_INSERT("RF", ip, idx + 1, 1, new, NULL,
-                       XFS_DATA_FORK);
-               xfs_iext_insert(ifp, idx + 1, 1, new);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+
+               xfs_iext_insert(ip, idx + 1, 1, new, state);
                ip->i_df.if_lastex = idx + 1;
                ip->i_d.di_nextents++;
                if (cur == NULL)
@@ -1756,19 +1641,18 @@ xfs_bmap_add_extent_unwritten_real(
                 * newext.  Contiguity is impossible here.
                 * One extent becomes three extents.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(ep,
                        new->br_startoff - PREV.br_startoff);
-               XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+
                r[0] = *new;
                r[1].br_startoff = new_endoff;
                r[1].br_blockcount =
                        PREV.br_startoff + PREV.br_blockcount - new_endoff;
                r[1].br_startblock = new->br_startblock + new->br_blockcount;
                r[1].br_state = oldext;
-               XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 2, &r[0], &r[1],
-                       XFS_DATA_FORK);
-               xfs_iext_insert(ifp, idx + 1, 2, &r[0]);
+               xfs_iext_insert(ip, idx + 1, 2, &r[0], state);
                ip->i_df.if_lastex = idx + 1;
                ip->i_d.di_nextents += 2;
                if (cur == NULL)
@@ -1813,13 +1697,13 @@ xfs_bmap_add_extent_unwritten_real(
                temp2 = PREV.br_blockcount;
                break;
 
-       case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
-       case MASK3(RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
-       case MASK2(LEFT_FILLING, RIGHT_CONTIG):
-       case MASK2(RIGHT_FILLING, LEFT_CONTIG):
-       case MASK2(LEFT_CONTIG, RIGHT_CONTIG):
-       case MASK(LEFT_CONTIG):
-       case MASK(RIGHT_CONTIG):
+       case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
+       case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
+       case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG:
+       case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
+       case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
+       case BMAP_LEFT_CONTIG:
+       case BMAP_RIGHT_CONTIG:
                /*
                 * These cases are all impossible.
                 */
@@ -1839,14 +1723,6 @@ done:
 #undef LEFT
 #undef RIGHT
 #undef PREV
-#undef MASK
-#undef MASK2
-#undef MASK3
-#undef MASK4
-#undef STATE_SET
-#undef STATE_TEST
-#undef STATE_SET_TEST
-#undef SWITCH_STATE
 }
 
 /*
@@ -1872,62 +1748,57 @@ xfs_bmap_add_extent_hole_delay(
        int                     state;  /* state bits, accessed thru macros */
        xfs_filblks_t           temp=0; /* temp for indirect calculations */
        xfs_filblks_t           temp2=0;
-       enum {                          /* bit number definitions for state */
-               LEFT_CONTIG,    RIGHT_CONTIG,
-               LEFT_DELAY,     RIGHT_DELAY,
-               LEFT_VALID,     RIGHT_VALID
-       };
-
-#define        MASK(b)                 (1 << (b))
-#define        MASK2(a,b)              (MASK(a) | MASK(b))
-#define        STATE_SET(b,v)          ((v) ? (state |= MASK(b)) : (state &= ~MASK(b)))
-#define        STATE_TEST(b)           (state & MASK(b))
-#define        STATE_SET_TEST(b,v)     ((v) ? ((state |= MASK(b)), 1) : \
-                                      ((state &= ~MASK(b)), 0))
-#define        SWITCH_STATE            (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG))
 
        ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
        ep = xfs_iext_get_ext(ifp, idx);
        state = 0;
        ASSERT(isnullstartblock(new->br_startblock));
+
        /*
         * Check and set flags if this segment has a left neighbor
         */
-       if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
+       if (idx > 0) {
+               state |= BMAP_LEFT_VALID;
                xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left);
-               STATE_SET(LEFT_DELAY, isnullstartblock(left.br_startblock));
+
+               if (isnullstartblock(left.br_startblock))
+                       state |= BMAP_LEFT_DELAY;
        }
+
        /*
         * Check and set flags if the current (right) segment exists.
         * If it doesn't exist, we're converting the hole at end-of-file.
         */
-       if (STATE_SET_TEST(RIGHT_VALID,
-                          idx <
-                          ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
+       if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
+               state |= BMAP_RIGHT_VALID;
                xfs_bmbt_get_all(ep, &right);
-               STATE_SET(RIGHT_DELAY, isnullstartblock(right.br_startblock));
+
+               if (isnullstartblock(right.br_startblock))
+                       state |= BMAP_RIGHT_DELAY;
        }
+
        /*
         * Set contiguity flags on the left and right neighbors.
         * Don't let extents get too large, even if the pieces are contiguous.
         */
-       STATE_SET(LEFT_CONTIG,
-               STATE_TEST(LEFT_VALID) && STATE_TEST(LEFT_DELAY) &&
-               left.br_startoff + left.br_blockcount == new->br_startoff &&
-               left.br_blockcount + new->br_blockcount <= MAXEXTLEN);
-       STATE_SET(RIGHT_CONTIG,
-               STATE_TEST(RIGHT_VALID) && STATE_TEST(RIGHT_DELAY) &&
-               new->br_startoff + new->br_blockcount == right.br_startoff &&
-               new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
-               (!STATE_TEST(LEFT_CONTIG) ||
-                (left.br_blockcount + new->br_blockcount +
-                    right.br_blockcount <= MAXEXTLEN)));
+       if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) &&
+           left.br_startoff + left.br_blockcount == new->br_startoff &&
+           left.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+               state |= BMAP_LEFT_CONTIG;
+
+       if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) &&
+           new->br_startoff + new->br_blockcount == right.br_startoff &&
+           new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
+           (!(state & BMAP_LEFT_CONTIG) ||
+            (left.br_blockcount + new->br_blockcount +
+             right.br_blockcount <= MAXEXTLEN)))
+               state |= BMAP_RIGHT_CONTIG;
+
        /*
         * Switch out based on the contiguity flags.
         */
-       switch (SWITCH_STATE) {
-
-       case MASK2(LEFT_CONTIG, RIGHT_CONTIG):
+       switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) {
+       case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
                /*
                 * New allocation is contiguous with delayed allocations
                 * on the left and on the right.
@@ -1935,8 +1806,8 @@ xfs_bmap_add_extent_hole_delay(
                 */
                temp = left.br_blockcount + new->br_blockcount +
                        right.br_blockcount;
-               XFS_BMAP_TRACE_PRE_UPDATE("LC|RC", ip, idx - 1,
-                       XFS_DATA_FORK);
+
+               trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp);
                oldlen = startblockval(left.br_startblock) +
                        startblockval(new->br_startblock) +
@@ -1944,53 +1815,52 @@ xfs_bmap_add_extent_hole_delay(
                newlen = xfs_bmap_worst_indlen(ip, temp);
                xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1),
                        nullstartblock((int)newlen));
-               XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1,
-                       XFS_DATA_FORK);
-               XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, XFS_DATA_FORK);
-               xfs_iext_remove(ifp, idx, 1);
+               trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
+
+               xfs_iext_remove(ip, idx, 1, state);
                ip->i_df.if_lastex = idx - 1;
                /* DELTA: Two in-core extents were replaced by one. */
                temp2 = temp;
                temp = left.br_startoff;
                break;
 
-       case MASK(LEFT_CONTIG):
+       case BMAP_LEFT_CONTIG:
                /*
                 * New allocation is contiguous with a delayed allocation
                 * on the left.
                 * Merge the new allocation with the left neighbor.
                 */
                temp = left.br_blockcount + new->br_blockcount;
-               XFS_BMAP_TRACE_PRE_UPDATE("LC", ip, idx - 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp);
                oldlen = startblockval(left.br_startblock) +
                        startblockval(new->br_startblock);
                newlen = xfs_bmap_worst_indlen(ip, temp);
                xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1),
                        nullstartblock((int)newlen));
-               XFS_BMAP_TRACE_POST_UPDATE("LC", ip, idx - 1,
-                       XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
+
                ip->i_df.if_lastex = idx - 1;
                /* DELTA: One in-core extent grew into a hole. */
                temp2 = temp;
                temp = left.br_startoff;
                break;
 
-       case MASK(RIGHT_CONTIG):
+       case BMAP_RIGHT_CONTIG:
                /*
                 * New allocation is contiguous with a delayed allocation
                 * on the right.
                 * Merge the new allocation with the right neighbor.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("RC", ip, idx, XFS_DATA_FORK);
+               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);
                newlen = xfs_bmap_worst_indlen(ip, temp);
                xfs_bmbt_set_allf(ep, new->br_startoff,
                        nullstartblock((int)newlen), temp, right.br_state);
-               XFS_BMAP_TRACE_POST_UPDATE("RC", ip, idx, XFS_DATA_FORK);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+
                ip->i_df.if_lastex = idx;
                /* DELTA: One in-core extent grew into a hole. */
                temp2 = temp;
@@ -2004,9 +1874,7 @@ xfs_bmap_add_extent_hole_delay(
                 * Insert a new entry.
                 */
                oldlen = newlen = 0;
-               XFS_BMAP_TRACE_INSERT("0", ip, idx, 1, new, NULL,
-                       XFS_DATA_FORK);
-               xfs_iext_insert(ifp, idx, 1, new);
+               xfs_iext_insert(ip, idx, 1, new, state);
                ip->i_df.if_lastex = idx;
                /* DELTA: A new in-core extent was added in a hole. */
                temp2 = new->br_blockcount;
@@ -2030,12 +1898,6 @@ xfs_bmap_add_extent_hole_delay(
        }
        *logflagsp = 0;
        return 0;
-#undef MASK
-#undef MASK2
-#undef STATE_SET
-#undef STATE_TEST
-#undef STATE_SET_TEST
-#undef SWITCH_STATE
 }
 
 /*
@@ -2062,83 +1924,75 @@ xfs_bmap_add_extent_hole_real(
        int                     state;  /* state bits, accessed thru macros */
        xfs_filblks_t           temp=0;
        xfs_filblks_t           temp2=0;
-       enum {                          /* bit number definitions for state */
-               LEFT_CONTIG,    RIGHT_CONTIG,
-               LEFT_DELAY,     RIGHT_DELAY,
-               LEFT_VALID,     RIGHT_VALID
-       };
-
-#define        MASK(b)                 (1 << (b))
-#define        MASK2(a,b)              (MASK(a) | MASK(b))
-#define        STATE_SET(b,v)          ((v) ? (state |= MASK(b)) : (state &= ~MASK(b)))
-#define        STATE_TEST(b)           (state & MASK(b))
-#define        STATE_SET_TEST(b,v)     ((v) ? ((state |= MASK(b)), 1) : \
-                                      ((state &= ~MASK(b)), 0))
-#define        SWITCH_STATE            (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG))
 
        ifp = XFS_IFORK_PTR(ip, whichfork);
        ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t));
        ep = xfs_iext_get_ext(ifp, idx);
        state = 0;
+
+       if (whichfork == XFS_ATTR_FORK)
+               state |= BMAP_ATTRFORK;
+
        /*
         * Check and set flags if this segment has a left neighbor.
         */
-       if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
+       if (idx > 0) {
+               state |= BMAP_LEFT_VALID;
                xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left);
-               STATE_SET(LEFT_DELAY, isnullstartblock(left.br_startblock));
+               if (isnullstartblock(left.br_startblock))
+                       state |= BMAP_LEFT_DELAY;
        }
+
        /*
         * Check and set flags if this segment has a current value.
         * Not true if we're inserting into the "hole" at eof.
         */
-       if (STATE_SET_TEST(RIGHT_VALID,
-                          idx <
-                          ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
+       if (idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
+               state |= BMAP_RIGHT_VALID;
                xfs_bmbt_get_all(ep, &right);
-               STATE_SET(RIGHT_DELAY, isnullstartblock(right.br_startblock));
+               if (isnullstartblock(right.br_startblock))
+                       state |= BMAP_RIGHT_DELAY;
        }
+
        /*
         * We're inserting a real allocation between "left" and "right".
         * Set the contiguity flags.  Don't let extents get too large.
         */
-       STATE_SET(LEFT_CONTIG,
-               STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) &&
-               left.br_startoff + left.br_blockcount == new->br_startoff &&
-               left.br_startblock + left.br_blockcount == new->br_startblock &&
-               left.br_state == new->br_state &&
-               left.br_blockcount + new->br_blockcount <= MAXEXTLEN);
-       STATE_SET(RIGHT_CONTIG,
-               STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) &&
-               new->br_startoff + new->br_blockcount == right.br_startoff &&
-               new->br_startblock + new->br_blockcount ==
-                   right.br_startblock &&
-               new->br_state == right.br_state &&
-               new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
-               (!STATE_TEST(LEFT_CONTIG) ||
-                left.br_blockcount + new->br_blockcount +
-                    right.br_blockcount <= MAXEXTLEN));
+       if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) &&
+           left.br_startoff + left.br_blockcount == new->br_startoff &&
+           left.br_startblock + left.br_blockcount == new->br_startblock &&
+           left.br_state == new->br_state &&
+           left.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+               state |= BMAP_LEFT_CONTIG;
+
+       if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
+           new->br_startoff + new->br_blockcount == right.br_startoff &&
+           new->br_startblock + new->br_blockcount == right.br_startblock &&
+           new->br_state == right.br_state &&
+           new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
+           (!(state & BMAP_LEFT_CONTIG) ||
+            left.br_blockcount + new->br_blockcount +
+            right.br_blockcount <= MAXEXTLEN))
+               state |= BMAP_RIGHT_CONTIG;
 
        error = 0;
        /*
         * Select which case we're in here, and implement it.
         */
-       switch (SWITCH_STATE) {
-
-       case MASK2(LEFT_CONTIG, RIGHT_CONTIG):
+       switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) {
+       case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
                /*
                 * New allocation is contiguous with real allocations on the
                 * left and on the right.
                 * Merge all three into a single extent record.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LC|RC", ip, idx - 1,
-                       whichfork);
+               trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
                        left.br_blockcount + new->br_blockcount +
                        right.br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1,
-                       whichfork);
-               XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, whichfork);
-               xfs_iext_remove(ifp, idx, 1);
+               trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
+
+               xfs_iext_remove(ip, idx, 1, state);
                ifp->if_lastex = idx - 1;
                XFS_IFORK_NEXT_SET(ip, whichfork,
                        XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
@@ -2173,16 +2027,17 @@ xfs_bmap_add_extent_hole_real(
                        right.br_blockcount;
                break;
 
-       case MASK(LEFT_CONTIG):
+       case BMAP_LEFT_CONTIG:
                /*
                 * New allocation is contiguous with a real allocation
                 * on the left.
                 * Merge the new allocation with the left neighbor.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("LC", ip, idx - 1, whichfork);
+               trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
                        left.br_blockcount + new->br_blockcount);
-               XFS_BMAP_TRACE_POST_UPDATE("LC", ip, idx - 1, whichfork);
+               trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
+
                ifp->if_lastex = idx - 1;
                if (cur == NULL) {
                        rval = xfs_ilog_fext(whichfork);
@@ -2207,17 +2062,18 @@ xfs_bmap_add_extent_hole_real(
                        new->br_blockcount;
                break;
 
-       case MASK(RIGHT_CONTIG):
+       case BMAP_RIGHT_CONTIG:
                /*
                 * New allocation is contiguous with a real allocation
                 * on the right.
                 * Merge the new allocation with the right neighbor.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("RC", ip, idx, whichfork);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock,
                        new->br_blockcount + right.br_blockcount,
                        right.br_state);
-               XFS_BMAP_TRACE_POST_UPDATE("RC", ip, idx, whichfork);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+
                ifp->if_lastex = idx;
                if (cur == NULL) {
                        rval = xfs_ilog_fext(whichfork);
@@ -2248,8 +2104,7 @@ xfs_bmap_add_extent_hole_real(
                 * real allocation.
                 * Insert a new entry.
                 */
-               XFS_BMAP_TRACE_INSERT("0", ip, idx, 1, new, NULL, whichfork);
-               xfs_iext_insert(ifp, idx, 1, new);
+               xfs_iext_insert(ip, idx, 1, new, state);
                ifp->if_lastex = idx;
                XFS_IFORK_NEXT_SET(ip, whichfork,
                        XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
@@ -2283,12 +2138,6 @@ xfs_bmap_add_extent_hole_real(
 done:
        *logflagsp = rval;
        return error;
-#undef MASK
-#undef MASK2
-#undef STATE_SET
-#undef STATE_TEST
-#undef STATE_SET_TEST
-#undef SWITCH_STATE
 }
 
 /*
@@ -2691,7 +2540,7 @@ xfs_bmap_rtalloc(
                 * Adjust the disk quota also. This was reserved
                 * earlier.
                 */
-               XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
+               xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
                        ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
                                        XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
        } else {
@@ -2995,7 +2844,7 @@ xfs_bmap_btalloc(
                 * Adjust the disk quota also. This was reserved
                 * earlier.
                 */
-               XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
+               xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
                        ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT :
                                        XFS_TRANS_DQ_BCOUNT,
                        (long) args.len);
@@ -3066,7 +2915,7 @@ xfs_bmap_btree_to_extents(
                return error;
        xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp);
        ip->i_d.di_nblocks--;
-       XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
+       xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
        xfs_trans_binval(tp, cbp);
        if (cur->bc_bufs[0] == cbp)
                cur->bc_bufs[0] = NULL;
@@ -3115,8 +2964,13 @@ xfs_bmap_del_extent(
        uint                    qfield; /* quota field to update */
        xfs_filblks_t           temp;   /* for indirect length calculations */
        xfs_filblks_t           temp2;  /* for indirect length calculations */
+       int                     state = 0;
 
        XFS_STATS_INC(xs_del_exlist);
+
+       if (whichfork == XFS_ATTR_FORK)
+               state |= BMAP_ATTRFORK;
+
        mp = ip->i_mount;
        ifp = XFS_IFORK_PTR(ip, whichfork);
        ASSERT((idx >= 0) && (idx < ifp->if_bytes /
@@ -3196,8 +3050,8 @@ xfs_bmap_del_extent(
                /*
                 * Matches the whole extent.  Delete the entry.
                 */
-               XFS_BMAP_TRACE_DELETE("3", ip, idx, 1, whichfork);
-               xfs_iext_remove(ifp, idx, 1);
+               xfs_iext_remove(ip, idx, 1,
+                               whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0);
                ifp->if_lastex = idx;
                if (delay)
                        break;
@@ -3217,7 +3071,7 @@ xfs_bmap_del_extent(
                /*
                 * Deleting the first part of the extent.
                 */
-               XFS_BMAP_TRACE_PRE_UPDATE("2", ip, idx, whichfork);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_startoff(ep, del_endoff);
                temp = got.br_blockcount - del->br_blockcount;
                xfs_bmbt_set_blockcount(ep, temp);
@@ -3226,13 +3080,12 @@ xfs_bmap_del_extent(
                        temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
                                da_old);
                        xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
-                       XFS_BMAP_TRACE_POST_UPDATE("2", ip, idx,
-                               whichfork);
+                       trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
                        da_new = temp;
                        break;
                }
                xfs_bmbt_set_startblock(ep, del_endblock);
-               XFS_BMAP_TRACE_POST_UPDATE("2", ip, idx, whichfork);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
                if (!cur) {
                        flags |= xfs_ilog_fext(whichfork);
                        break;
@@ -3248,19 +3101,18 @@ xfs_bmap_del_extent(
                 * Deleting the last part of the extent.
                 */
                temp = got.br_blockcount - del->br_blockcount;
-               XFS_BMAP_TRACE_PRE_UPDATE("1", ip, idx, whichfork);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(ep, temp);
                ifp->if_lastex = idx;
                if (delay) {
                        temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
                                da_old);
                        xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
-                       XFS_BMAP_TRACE_POST_UPDATE("1", ip, idx,
-                               whichfork);
+                       trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
                        da_new = temp;
                        break;
                }
-               XFS_BMAP_TRACE_POST_UPDATE("1", ip, idx, whichfork);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
                if (!cur) {
                        flags |= xfs_ilog_fext(whichfork);
                        break;
@@ -3277,7 +3129,7 @@ xfs_bmap_del_extent(
                 * Deleting the middle of the extent.
                 */
                temp = del->br_startoff - got.br_startoff;
-               XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, whichfork);
+               trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
                xfs_bmbt_set_blockcount(ep, temp);
                new.br_startoff = del_endoff;
                temp2 = got_endoff - del_endoff;
@@ -3364,10 +3216,8 @@ xfs_bmap_del_extent(
                                }
                        }
                }
-               XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, whichfork);
-               XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 1, &new, NULL,
-                       whichfork);
-               xfs_iext_insert(ifp, idx + 1, 1, &new);
+               trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
+               xfs_iext_insert(ip, idx + 1, 1, &new, state);
                ifp->if_lastex = idx + 1;
                break;
        }
@@ -3386,7 +3236,7 @@ xfs_bmap_del_extent(
         * Adjust quota data.
         */
        if (qfield)
-               XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, qfield, (long)-nblks);
+               xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks);
 
        /*
         * Account for change in delayed indirect blocks.
@@ -3523,7 +3373,7 @@ xfs_bmap_extents_to_btree(
        *firstblock = cur->bc_private.b.firstblock = args.fsbno;
        cur->bc_private.b.allocated++;
        ip->i_d.di_nblocks++;
-       XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
+       xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
        abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0);
        /*
         * Fill in the child block.
@@ -3569,6 +3419,27 @@ xfs_bmap_extents_to_btree(
 }
 
 /*
+ * Calculate the default attribute fork offset for newly created inodes.
+ */
+uint
+xfs_default_attroffset(
+       struct xfs_inode        *ip)
+{
+       struct xfs_mount        *mp = ip->i_mount;
+       uint                    offset;
+
+       if (mp->m_sb.sb_inodesize == 256) {
+               offset = XFS_LITINO(mp) -
+                               XFS_BMDR_SPACE_CALC(MINABTPTRS);
+       } else {
+               offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
+       }
+
+       ASSERT(offset < XFS_LITINO(mp));
+       return offset;
+}
+
+/*
  * Helper routine to reset inode di_forkoff field when switching
  * attribute fork from local to extent format - we reset it where
  * possible to make space available for inline data fork extents.
@@ -3580,15 +3451,18 @@ xfs_bmap_forkoff_reset(
        int             whichfork)
 {
        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) &&
-           ((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) {
-               ip->i_d.di_forkoff = mp->m_attroffset >> 3;
-               ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) /
-                                       (uint)sizeof(xfs_bmbt_rec_t);
-               ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) /
-                                       (uint)sizeof(xfs_bmbt_rec_t);
+           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;
+
+               if (dfl_forkoff > ip->i_d.di_forkoff) {
+                       ip->i_d.di_forkoff = dfl_forkoff;
+                       ip->i_df.if_ext_max =
+                               XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
+                       ip->i_afp->if_ext_max =
+                               XFS_IFORK_ASIZE(ip) / sizeof(xfs_bmbt_rec_t);
+               }
        }
 }
 
@@ -3663,10 +3537,12 @@ xfs_bmap_local_to_extents(
                xfs_iext_add(ifp, 0, 1);
                ep = xfs_iext_get_ext(ifp, 0);
                xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM);
-               XFS_BMAP_TRACE_POST_UPDATE("new", ip, 0, whichfork);
+               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(args.mp, tp, ip,
+               xfs_trans_mod_dquot_byino(tp, ip,
                        XFS_TRANS_DQ_BCOUNT, 1L);
                flags |= xfs_ilog_fext(whichfork);
        } else {
@@ -3689,7 +3565,7 @@ done:
  * entry (null if none).  Else, *lastxp will be set to the index
  * of the found entry; *gotp will contain the entry.
  */
-xfs_bmbt_rec_host_t *                  /* pointer to found extent entry */
+STATIC xfs_bmbt_rec_host_t *           /* pointer to found extent entry */
 xfs_bmap_search_multi_extents(
        xfs_ifork_t     *ifp,           /* inode fork pointer */
        xfs_fileoff_t   bno,            /* block number searched for */
@@ -3776,158 +3652,6 @@ xfs_bmap_search_extents(
        return ep;
 }
 
-
-#ifdef XFS_BMAP_TRACE
-ktrace_t       *xfs_bmap_trace_buf;
-
-/*
- * Add a bmap trace buffer entry.  Base routine for the others.
- */
-STATIC void
-xfs_bmap_trace_addentry(
-       int             opcode,         /* operation */
-       const char      *fname,         /* function name */
-       char            *desc,          /* operation description */
-       xfs_inode_t     *ip,            /* incore inode pointer */
-       xfs_extnum_t    idx,            /* index of entry(ies) */
-       xfs_extnum_t    cnt,            /* count of entries, 1 or 2 */
-       xfs_bmbt_rec_host_t *r1,        /* first record */
-       xfs_bmbt_rec_host_t *r2,        /* second record or null */
-       int             whichfork)      /* data or attr fork */
-{
-       xfs_bmbt_rec_host_t tr2;
-
-       ASSERT(cnt == 1 || cnt == 2);
-       ASSERT(r1 != NULL);
-       if (cnt == 1) {
-               ASSERT(r2 == NULL);
-               r2 = &tr2;
-               memset(&tr2, 0, sizeof(tr2));
-       } else
-               ASSERT(r2 != NULL);
-       ktrace_enter(xfs_bmap_trace_buf,
-               (void *)(__psint_t)(opcode | (whichfork << 16)),
-               (void *)fname, (void *)desc, (void *)ip,
-               (void *)(__psint_t)idx,
-               (void *)(__psint_t)cnt,
-               (void *)(__psunsigned_t)(ip->i_ino >> 32),
-               (void *)(__psunsigned_t)(unsigned)ip->i_ino,
-               (void *)(__psunsigned_t)(r1->l0 >> 32),
-               (void *)(__psunsigned_t)(unsigned)(r1->l0),
-               (void *)(__psunsigned_t)(r1->l1 >> 32),
-               (void *)(__psunsigned_t)(unsigned)(r1->l1),
-               (void *)(__psunsigned_t)(r2->l0 >> 32),
-               (void *)(__psunsigned_t)(unsigned)(r2->l0),
-               (void *)(__psunsigned_t)(r2->l1 >> 32),
-               (void *)(__psunsigned_t)(unsigned)(r2->l1)
-               );
-       ASSERT(ip->i_xtrace);
-       ktrace_enter(ip->i_xtrace,
-               (void *)(__psint_t)(opcode | (whichfork << 16)),
-               (void *)fname, (void *)desc, (void *)ip,
-               (void *)(__psint_t)idx,
-               (void *)(__psint_t)cnt,
-               (void *)(__psunsigned_t)(ip->i_ino >> 32),
-               (void *)(__psunsigned_t)(unsigned)ip->i_ino,
-               (void *)(__psunsigned_t)(r1->l0 >> 32),
-               (void *)(__psunsigned_t)(unsigned)(r1->l0),
-               (void *)(__psunsigned_t)(r1->l1 >> 32),
-               (void *)(__psunsigned_t)(unsigned)(r1->l1),
-               (void *)(__psunsigned_t)(r2->l0 >> 32),
-               (void *)(__psunsigned_t)(unsigned)(r2->l0),
-               (void *)(__psunsigned_t)(r2->l1 >> 32),
-               (void *)(__psunsigned_t)(unsigned)(r2->l1)
-               );
-}
-
-/*
- * Add bmap trace entry prior to a call to xfs_iext_remove.
- */
-STATIC void
-xfs_bmap_trace_delete(
-       const char      *fname,         /* function name */
-       char            *desc,          /* operation description */
-       xfs_inode_t     *ip,            /* incore inode pointer */
-       xfs_extnum_t    idx,            /* index of entry(entries) deleted */
-       xfs_extnum_t    cnt,            /* count of entries deleted, 1 or 2 */
-       int             whichfork)      /* data or attr fork */
-{
-       xfs_ifork_t     *ifp;           /* inode fork pointer */
-
-       ifp = XFS_IFORK_PTR(ip, whichfork);
-       xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_DELETE, fname, desc, ip, idx,
-               cnt, xfs_iext_get_ext(ifp, idx),
-               cnt == 2 ? xfs_iext_get_ext(ifp, idx + 1) : NULL,
-               whichfork);
-}
-
-/*
- * Add bmap trace entry prior to a call to xfs_iext_insert, or
- * reading in the extents list from the disk (in the btree).
- */
-STATIC void
-xfs_bmap_trace_insert(
-       const char      *fname,         /* function name */
-       char            *desc,          /* operation description */
-       xfs_inode_t     *ip,            /* incore inode pointer */
-       xfs_extnum_t    idx,            /* index of entry(entries) inserted */
-       xfs_extnum_t    cnt,            /* count of entries inserted, 1 or 2 */
-       xfs_bmbt_irec_t *r1,            /* inserted record 1 */
-       xfs_bmbt_irec_t *r2,            /* inserted record 2 or null */
-       int             whichfork)      /* data or attr fork */
-{
-       xfs_bmbt_rec_host_t tr1;        /* compressed record 1 */
-       xfs_bmbt_rec_host_t tr2;        /* compressed record 2 if needed */
-
-       xfs_bmbt_set_all(&tr1, r1);
-       if (cnt == 2) {
-               ASSERT(r2 != NULL);
-               xfs_bmbt_set_all(&tr2, r2);
-       } else {
-               ASSERT(cnt == 1);
-               ASSERT(r2 == NULL);
-       }
-       xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_INSERT, fname, desc, ip, idx,
-               cnt, &tr1, cnt == 2 ? &tr2 : NULL, whichfork);
-}
-
-/*
- * Add bmap trace entry after updating an extent record in place.
- */
-STATIC void
-xfs_bmap_trace_post_update(
-       const char      *fname,         /* function name */
-       char            *desc,          /* operation description */
-       xfs_inode_t     *ip,            /* incore inode pointer */
-       xfs_extnum_t    idx,            /* index of entry updated */
-       int             whichfork)      /* data or attr fork */
-{
-       xfs_ifork_t     *ifp;           /* inode fork pointer */
-
-       ifp = XFS_IFORK_PTR(ip, whichfork);
-       xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_POST_UP, fname, desc, ip, idx,
-               1, xfs_iext_get_ext(ifp, idx), NULL, whichfork);
-}
-
-/*
- * Add bmap trace entry prior to updating an extent record in place.
- */
-STATIC void
-xfs_bmap_trace_pre_update(
-       const char      *fname,         /* function name */
-       char            *desc,          /* operation description */
-       xfs_inode_t     *ip,            /* incore inode pointer */
-       xfs_extnum_t    idx,            /* index of entry to be updated */
-       int             whichfork)      /* data or attr fork */
-{
-       xfs_ifork_t     *ifp;           /* inode fork pointer */
-
-       ifp = XFS_IFORK_PTR(ip, whichfork);
-       xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_PRE_UP, fname, desc, ip, idx, 1,
-               xfs_iext_get_ext(ifp, idx), NULL, whichfork);
-}
-#endif /* XFS_BMAP_TRACE */
-
 /*
  * Compute the worst-case number of indirect blocks that will be used
  * for ip's delayed extent of length "len".
@@ -3959,37 +3683,6 @@ xfs_bmap_worst_indlen(
        return rval;
 }
 
-#if defined(XFS_RW_TRACE)
-STATIC void
-xfs_bunmap_trace(
-       xfs_inode_t             *ip,
-       xfs_fileoff_t           bno,
-       xfs_filblks_t           len,
-       int                     flags,
-       inst_t                  *ra)
-{
-       if (ip->i_rwtrace == NULL)
-               return;
-       ktrace_enter(ip->i_rwtrace,
-               (void *)(__psint_t)XFS_BUNMAP,
-               (void *)ip,
-               (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
-               (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
-               (void *)(__psint_t)(((xfs_dfiloff_t)bno >> 32) & 0xffffffff),
-               (void *)(__psint_t)((xfs_dfiloff_t)bno & 0xffffffff),
-               (void *)(__psint_t)len,
-               (void *)(__psint_t)flags,
-               (void *)(unsigned long)current_cpu(),
-               (void *)ra,
-               (void *)0,
-               (void *)0,
-               (void *)0,
-               (void *)0,
-               (void *)0,
-               (void *)0);
-}
-#endif
-
 /*
  * Convert inode from non-attributed to attributed.
  * Must not be in a transaction, ip must not be locked.
@@ -4024,7 +3717,7 @@ xfs_bmap_add_attrfork(
                        XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT)))
                goto error0;
        xfs_ilock(ip, XFS_ILOCK_EXCL);
-       error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, blks, 0, rsvd ?
+       error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
                        XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
                        XFS_QMOPT_RES_REGBLKS);
        if (error) {
@@ -4057,7 +3750,7 @@ xfs_bmap_add_attrfork(
        case XFS_DINODE_FMT_BTREE:
                ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
                if (!ip->i_d.di_forkoff)
-                       ip->i_d.di_forkoff = mp->m_attroffset >> 3;
+                       ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
                else if (mp->m_flags & XFS_MOUNT_ATTR2)
                        version = 2;
                break;
@@ -4204,12 +3897,12 @@ xfs_bmap_compute_maxlevels(
         * (a signed 16-bit number, xfs_aextnum_t).
         *
         * Note that we can no longer assume that if we are in ATTR1 that
-        * the fork offset of all the inodes will be (m_attroffset >> 3)
-        * because we could have mounted with ATTR2 and then mounted back
-        * with ATTR1, keeping the di_forkoff's fixed but probably at
-        * various positions. Therefore, for both ATTR1 and ATTR2
-        * we have to assume the worst case scenario of a minimum size
-        * available.
+        * the fork offset of all the inodes will be
+        * (xfs_default_attroffset(ip) >> 3) because we could have mounted
+        * with ATTR2 and then mounted back with ATTR1, keeping the
+        * di_forkoff's fixed but probably at various positions. Therefore,
+        * for both ATTR1 and ATTR2 we have to assume the worst case scenario
+        * of a minimum size available.
         */
        if (whichfork == XFS_DATA_FORK) {
                maxleafents = MAXEXTNUM;
@@ -4678,34 +4371,30 @@ error0:
        return XFS_ERROR(EFSCORRUPTED);
 }
 
-#ifdef XFS_BMAP_TRACE
+#ifdef DEBUG
 /*
  * Add bmap trace insert entries for all the contents of the extent records.
  */
 void
 xfs_bmap_trace_exlist(
-       const char      *fname,         /* function name */
        xfs_inode_t     *ip,            /* incore inode pointer */
        xfs_extnum_t    cnt,            /* count of entries in the list */
-       int             whichfork)      /* data or attr fork */
+       int             whichfork,      /* data or attr fork */
+       unsigned long   caller_ip)
 {
-       xfs_bmbt_rec_host_t *ep;        /* current extent record */
        xfs_extnum_t    idx;            /* extent record index */
        xfs_ifork_t     *ifp;           /* inode fork pointer */
-       xfs_bmbt_irec_t s;              /* file extent record */
+       int             state = 0;
+
+       if (whichfork == XFS_ATTR_FORK)
+               state |= BMAP_ATTRFORK;
 
        ifp = XFS_IFORK_PTR(ip, whichfork);
        ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
-       for (idx = 0; idx < cnt; idx++) {
-               ep = xfs_iext_get_ext(ifp, idx);
-               xfs_bmbt_get_all(ep, &s);
-               XFS_BMAP_TRACE_INSERT("exlist", ip, idx, 1, &s, NULL,
-                       whichfork);
-       }
+       for (idx = 0; idx < cnt; idx++)
+               trace_xfs_extlist(ip, idx, whichfork, caller_ip);
 }
-#endif
 
-#ifdef DEBUG
 /*
  * Validate that the bmbt_irecs being returned from bmapi are valid
  * given the callers original parameters.  Specifically check the
@@ -4959,10 +4648,11 @@ xfs_bmapi(
                                 * adjusted later.  We return if we haven't
                                 * allocated blocks already inside this loop.
                                 */
-                               if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS(
-                                               mp, NULL, ip, (long)alen, 0,
+                               error = xfs_trans_reserve_quota_nblks(
+                                               NULL, ip, (long)alen, 0,
                                                rt ? XFS_QMOPT_RES_RTBLKS :
-                                                    XFS_QMOPT_RES_REGBLKS))) {
+                                                    XFS_QMOPT_RES_REGBLKS);
+                               if (error) {
                                        if (n == 0) {
                                                *nmap = 0;
                                                ASSERT(cur == NULL);
@@ -5011,8 +4701,8 @@ xfs_bmapi(
                                        if (XFS_IS_QUOTA_ON(mp))
                                                /* unreserve the blocks now */
                                                (void)
-                                               XFS_TRANS_UNRESERVE_QUOTA_NBLKS(
-                                                       mp, NULL, ip,
+                                               xfs_trans_unreserve_quota_nblks(
+                                                       NULL, ip,
                                                        (long)alen, 0, rt ?
                                                        XFS_QMOPT_RES_RTBLKS :
                                                        XFS_QMOPT_RES_REGBLKS);
@@ -5453,7 +5143,8 @@ xfs_bunmapi(
        int                     rsvd;           /* OK to allocate reserved blocks */
        xfs_fsblock_t           sum;
 
-       xfs_bunmap_trace(ip, bno, len, flags, (inst_t *)__return_address);
+       trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_);
+
        whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
                XFS_ATTR_FORK : XFS_DATA_FORK;
        ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -5667,14 +5358,14 @@ xfs_bunmapi(
                                do_div(rtexts, mp->m_sb.sb_rextsize);
                                xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
                                                (int64_t)rtexts, rsvd);
-                               (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,
-                                       NULL, ip, -((long)del.br_blockcount), 0,
+                               (void)xfs_trans_reserve_quota_nblks(NULL,
+                                       ip, -((long)del.br_blockcount), 0,
                                        XFS_QMOPT_RES_RTBLKS);
                        } else {
                                xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
                                                (int64_t)del.br_blockcount, rsvd);
-                               (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,
-                                       NULL, ip, -((long)del.br_blockcount), 0,
+                               (void)xfs_trans_reserve_quota_nblks(NULL,
+                                       ip, -((long)del.br_blockcount), 0,
                                        XFS_QMOPT_RES_REGBLKS);
                        }
                        ip->i_delayed_blks -= del.br_blockcount;
@@ -5856,7 +5547,7 @@ xfs_getbmap(
        void                    *arg)           /* formatter arg */
 {
        __int64_t               bmvend;         /* last block requested */
-       int                     error;          /* return value */
+       int                     error = 0;      /* return value */
        __int64_t               fixlen;         /* length for -1 case */
        int                     i;              /* extent number */
        int                     lock;           /* lock state */
@@ -5866,39 +5557,18 @@ xfs_getbmap(
        int                     nexleft;        /* # of user extents left */
        int                     subnex;         /* # of bmapi's can do */
        int                     nmap;           /* number of map entries */
-       struct getbmapx         out;            /* output structure */
+       struct getbmapx         *out;           /* output structure */
        int                     whichfork;      /* data or attr fork */
        int                     prealloced;     /* this is a file with
                                                 * preallocated data space */
        int                     iflags;         /* interface flags */
        int                     bmapi_flags;    /* flags for xfs_bmapi */
+       int                     cur_ext = 0;
 
        mp = ip->i_mount;
        iflags = bmv->bmv_iflags;
-
        whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
 
-       /*      If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
-        *      generate a DMAPI read event.  Otherwise, if the DM_EVENT_READ
-        *      bit is set for the file, generate a read event in order
-        *      that the DMAPI application may do its thing before we return
-        *      the extents.  Usually this means restoring user file data to
-        *      regions of the file that look like holes.
-        *
-        *      The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
-        *      BMV_IF_NO_DMAPI_READ so that read events are generated.
-        *      If this were not true, callers of ioctl( XFS_IOC_GETBMAP )
-        *      could misinterpret holes in a DMAPI file as true holes,
-        *      when in fact they may represent offline user data.
-        */
-       if ((iflags & BMV_IF_NO_DMAPI_READ) == 0 &&
-           DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
-           whichfork == XFS_DATA_FORK) {
-               error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL);
-               if (error)
-                       return XFS_ERROR(error);
-       }
-
        if (whichfork == XFS_ATTR_FORK) {
                if (XFS_IFORK_Q(ip)) {
                        if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS &&
@@ -5912,11 +5582,37 @@ xfs_getbmap(
                                         ip->i_mount);
                        return XFS_ERROR(EFSCORRUPTED);
                }
-       } else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
-                  ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
-                  ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
-               return XFS_ERROR(EINVAL);
-       if (whichfork == XFS_DATA_FORK) {
+
+               prealloced = 0;
+               fixlen = 1LL << 32;
+       } else {
+               /*
+                * If the BMV_IF_NO_DMAPI_READ interface bit specified, do
+                * not generate a DMAPI read event.  Otherwise, if the
+                * DM_EVENT_READ bit is set for the file, generate a read
+                * event in order that the DMAPI application may do its thing
+                * before we return the extents.  Usually this means restoring
+                * user file data to regions of the file that look like holes.
+                *
+                * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
+                * BMV_IF_NO_DMAPI_READ so that read events are generated.
+                * If this were not true, callers of ioctl(XFS_IOC_GETBMAP)
+                * could misinterpret holes in a DMAPI file as true holes,
+                * when in fact they may represent offline user data.
+                */
+               if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
+                   !(iflags & BMV_IF_NO_DMAPI_READ)) {
+                       error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip,
+                                             0, 0, 0, NULL);
+                       if (error)
+                               return XFS_ERROR(error);
+               }
+
+               if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
+                   ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
+                   ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
+                       return XFS_ERROR(EINVAL);
+
                if (xfs_get_extsz_hint(ip) ||
                    ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){
                        prealloced = 1;
@@ -5925,42 +5621,41 @@ xfs_getbmap(
                        prealloced = 0;
                        fixlen = ip->i_size;
                }
-       } else {
-               prealloced = 0;
-               fixlen = 1LL << 32;
        }
 
        if (bmv->bmv_length == -1) {
                fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, fixlen));
-               bmv->bmv_length = MAX( (__int64_t)(fixlen - bmv->bmv_offset),
-                                       (__int64_t)0);
-       } else if (bmv->bmv_length < 0)
-               return XFS_ERROR(EINVAL);
-       if (bmv->bmv_length == 0) {
+               bmv->bmv_length =
+                       max_t(__int64_t, fixlen - bmv->bmv_offset, 0);
+       } else if (bmv->bmv_length == 0) {
                bmv->bmv_entries = 0;
                return 0;
+       } else if (bmv->bmv_length < 0) {
+               return XFS_ERROR(EINVAL);
        }
+
        nex = bmv->bmv_count - 1;
        if (nex <= 0)
                return XFS_ERROR(EINVAL);
        bmvend = bmv->bmv_offset + bmv->bmv_length;
 
-       xfs_ilock(ip, XFS_IOLOCK_SHARED);
 
-       if (((iflags & BMV_IF_DELALLOC) == 0) &&
-           (whichfork == XFS_DATA_FORK) &&
-           (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
-               /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
-               error = xfs_flush_pages(ip, (xfs_off_t)0,
-                                              -1, 0, FI_REMAPF);
-               if (error) {
-                       xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-               return error;
+       if (bmv->bmv_count > ULONG_MAX / sizeof(struct getbmapx))
+               return XFS_ERROR(ENOMEM);
+       out = kmem_zalloc(bmv->bmv_count * sizeof(struct getbmapx), KM_MAYFAIL);
+       if (!out)
+               return XFS_ERROR(ENOMEM);
+
+       xfs_ilock(ip, XFS_IOLOCK_SHARED);
+       if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
+               if (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size) {
+                       error = xfs_flush_pages(ip, 0, -1, 0, FI_REMAPF);
+                       if (error)
+                               goto out_unlock_iolock;
                }
-       }
 
-       ASSERT(whichfork == XFS_ATTR_FORK || (iflags & BMV_IF_DELALLOC) ||
-              ip->i_delayed_blks == 0);
+               ASSERT(ip->i_delayed_blks == 0);
+       }
 
        lock = xfs_ilock_map_shared(ip);
 
@@ -5971,23 +5666,25 @@ xfs_getbmap(
        if (nex > XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1)
                nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1;
 
-       bmapi_flags = xfs_bmapi_aflag(whichfork) |
-                       ((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE);
+       bmapi_flags = xfs_bmapi_aflag(whichfork);
+       if (!(iflags & BMV_IF_PREALLOC))
+               bmapi_flags |= XFS_BMAPI_IGSTATE;
 
        /*
         * Allocate enough space to handle "subnex" maps at a time.
         */
+       error = ENOMEM;
        subnex = 16;
-       map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP);
+       map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL | KM_NOFS);
+       if (!map)
+               goto out_unlock_ilock;
 
        bmv->bmv_entries = 0;
 
-       if ((XFS_IFORK_NEXTENTS(ip, whichfork) == 0)) {
-               if (((iflags & BMV_IF_DELALLOC) == 0) ||
-                   whichfork == XFS_ATTR_FORK) {
-                       error = 0;
-                       goto unlock_and_return;
-               }
+       if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0 &&
+           (whichfork == XFS_ATTR_FORK || !(iflags & BMV_IF_DELALLOC))) {
+               error = 0;
+               goto out_free_map;
        }
 
        nexleft = nex;
@@ -5999,54 +5696,63 @@ xfs_getbmap(
                                  bmapi_flags, NULL, 0, map, &nmap,
                                  NULL, NULL);
                if (error)
-                       goto unlock_and_return;
+                       goto out_free_map;
                ASSERT(nmap <= subnex);
 
                for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
-                       out.bmv_oflags = 0;
+                       out[cur_ext].bmv_oflags = 0;
                        if (map[i].br_state == XFS_EXT_UNWRITTEN)
-                               out.bmv_oflags |= BMV_OF_PREALLOC;
+                               out[cur_ext].bmv_oflags |= BMV_OF_PREALLOC;
                        else if (map[i].br_startblock == DELAYSTARTBLOCK)
-                               out.bmv_oflags |= BMV_OF_DELALLOC;
-                       out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff);
-                       out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
-                       out.bmv_unused1 = out.bmv_unused2 = 0;
+                               out[cur_ext].bmv_oflags |= BMV_OF_DELALLOC;
+                       out[cur_ext].bmv_offset =
+                               XFS_FSB_TO_BB(mp, map[i].br_startoff);
+                       out[cur_ext].bmv_length =
+                               XFS_FSB_TO_BB(mp, map[i].br_blockcount);
+                       out[cur_ext].bmv_unused1 = 0;
+                       out[cur_ext].bmv_unused2 = 0;
                        ASSERT(((iflags & BMV_IF_DELALLOC) != 0) ||
                              (map[i].br_startblock != DELAYSTARTBLOCK));
                         if (map[i].br_startblock == HOLESTARTBLOCK &&
                            whichfork == XFS_ATTR_FORK) {
                                /* came to the end of attribute fork */
-                               out.bmv_oflags |= BMV_OF_LAST;
-                               goto unlock_and_return;
-                       } else {
-                               int full = 0;   /* user array is full */
-
-                               if (!xfs_getbmapx_fix_eof_hole(ip, &out,
-                                                       prealloced, bmvend,
-                                                       map[i].br_startblock)) {
-                                       goto unlock_and_return;
-                               }
-
-                               /* format results & advance arg */
-                               error = formatter(&arg, &out, &full);
-                               if (error || full)
-                                       goto unlock_and_return;
-                               nexleft--;
-                               bmv->bmv_offset =
-                                       out.bmv_offset + out.bmv_length;
-                               bmv->bmv_length = MAX((__int64_t)0,
-                                       (__int64_t)(bmvend - bmv->bmv_offset));
-                               bmv->bmv_entries++;
+                               out[cur_ext].bmv_oflags |= BMV_OF_LAST;
+                               goto out_free_map;
                        }
+
+                       if (!xfs_getbmapx_fix_eof_hole(ip, &out[cur_ext],
+                                       prealloced, bmvend,
+                                       map[i].br_startblock))
+                               goto out_free_map;
+
+                       nexleft--;
+                       bmv->bmv_offset =
+                               out[cur_ext].bmv_offset +
+                               out[cur_ext].bmv_length;
+                       bmv->bmv_length =
+                               max_t(__int64_t, 0, bmvend - bmv->bmv_offset);
+                       bmv->bmv_entries++;
+                       cur_ext++;
                }
        } while (nmap && nexleft && bmv->bmv_length);
 
-unlock_and_return:
+ out_free_map:
+       kmem_free(map);
+ out_unlock_ilock:
        xfs_iunlock_map_shared(ip, lock);
+ out_unlock_iolock:
        xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 
-       kmem_free(map);
+       for (i = 0; i < cur_ext; i++) {
+               int full = 0;   /* user array is full */
+
+               /* format results & advance arg */
+               error = formatter(&arg, &out[i], &full);
+               if (error || full)
+                       break;
+       }
 
+       kmem_free(out);
        return error;
 }