]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/xfs/xfs_bmap.c
Merge with ../linux-2.6
[linux-2.6-omap-h63xx.git] / fs / xfs / xfs_bmap.c
index 6f5d283888aa2b9ab243d93f8df1fe25c4e8cc34..e415a4698e9c3e30836f5c2578f40f2f921592c0 100644 (file)
@@ -1,68 +1,53 @@
 /*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation.
  *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
-
 #include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
 #include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
 #include "xfs_log.h"
+#include "xfs_inum.h"
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
 #include "xfs_dir.h"
 #include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
+#include "xfs_da_btree.h"
 #include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
 #include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
-#include "xfs_inode_item.h"
 #include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_dmapi.h"
+#include "xfs_mount.h"
+#include "xfs_ialloc.h"
 #include "xfs_itable.h"
+#include "xfs_inode_item.h"
 #include "xfs_extfree_item.h"
 #include "xfs_alloc.h"
 #include "xfs_bmap.h"
 #include "xfs_rtalloc.h"
 #include "xfs_error.h"
-#include "xfs_da_btree.h"
 #include "xfs_dir_leaf.h"
-#include "xfs_bit.h"
+#include "xfs_attr_leaf.h"
 #include "xfs_rw.h"
 #include "xfs_quota.h"
 #include "xfs_trans_space.h"
@@ -438,6 +423,12 @@ xfs_bmap_count_leaves(
        int                     numrecs,
        int                     *count);
 
+STATIC int
+xfs_bmap_disk_count_leaves(
+       xfs_bmbt_rec_t          *frp,
+       int                     numrecs,
+       int                     *count);
+
 /*
  * Bmap internal routines.
  */
@@ -2772,8 +2763,8 @@ xfs_bmap_btree_to_extents(
        ASSERT(ifp->if_flags & XFS_IFEXTENTS);
        ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
        rblock = ifp->if_broot;
-       ASSERT(INT_GET(rblock->bb_level, ARCH_CONVERT) == 1);
-       ASSERT(INT_GET(rblock->bb_numrecs, ARCH_CONVERT) == 1);
+       ASSERT(be16_to_cpu(rblock->bb_level) == 1);
+       ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1);
        ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1);
        mp = ip->i_mount;
        pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes);
@@ -3216,11 +3207,11 @@ xfs_bmap_extents_to_btree(
         * Fill in the root.
         */
        block = ifp->if_broot;
-       INT_SET(block->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC);
-       INT_SET(block->bb_level, ARCH_CONVERT, 1);
-       INT_SET(block->bb_numrecs, ARCH_CONVERT, 1);
-       INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLDFSBNO);
-       INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLDFSBNO);
+       block->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
+       block->bb_level = cpu_to_be16(1);
+       block->bb_numrecs = cpu_to_be16(1);
+       block->bb_leftsib = cpu_to_be64(NULLDFSBNO);
+       block->bb_rightsib = cpu_to_be64(NULLDFSBNO);
        /*
         * Need a cursor.  Can't allocate until bb_level is filled in.
         */
@@ -3273,10 +3264,10 @@ xfs_bmap_extents_to_btree(
         * Fill in the child block.
         */
        ablock = XFS_BUF_TO_BMBT_BLOCK(abp);
-       INT_SET(ablock->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC);
+       ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
        ablock->bb_level = 0;
-       INT_SET(ablock->bb_leftsib, ARCH_CONVERT, NULLDFSBNO);
-       INT_SET(ablock->bb_rightsib, ARCH_CONVERT, NULLDFSBNO);
+       ablock->bb_leftsib = cpu_to_be64(NULLDFSBNO);
+       ablock->bb_rightsib = cpu_to_be64(NULLDFSBNO);
        arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
        nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
        for (ep = ifp->if_u1.if_extents, cnt = i = 0; i < nextents; i++, ep++) {
@@ -3286,8 +3277,8 @@ xfs_bmap_extents_to_btree(
                        arp++; cnt++;
                }
        }
-       INT_SET(ablock->bb_numrecs, ARCH_CONVERT, cnt);
-       ASSERT(INT_GET(ablock->bb_numrecs, ARCH_CONVERT) == XFS_IFORK_NEXTENTS(ip, whichfork));
+       ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork));
+       ablock->bb_numrecs = cpu_to_be16(cnt);
        /*
         * Fill in the root key and pointer.
         */
@@ -3301,7 +3292,7 @@ xfs_bmap_extents_to_btree(
         * the root is at the right level.
         */
        xfs_bmbt_log_block(cur, abp, XFS_BB_ALL_BITS);
-       xfs_bmbt_log_recs(cur, abp, 1, INT_GET(ablock->bb_numrecs, ARCH_CONVERT));
+       xfs_bmbt_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
        ASSERT(*curp == NULL);
        *curp = cur;
        *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FBROOT(whichfork);
@@ -3336,6 +3327,29 @@ xfs_bmap_insert_exlist(
                xfs_bmbt_set_all(&base[to], new);
 }
 
+/*
+ * 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.
+ */
+STATIC void
+xfs_bmap_forkoff_reset(
+       xfs_mount_t     *mp,
+       xfs_inode_t     *ip,
+       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) &&
+           ((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);
+       }
+}
+
 /*
  * Convert a local file to an extents file.
  * This code is out of bounds for data forks of regular files,
@@ -3403,6 +3417,7 @@ xfs_bmap_local_to_extents(
                memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data,
                        ifp->if_bytes);
                xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
+               xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
                xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
                xfs_iext_realloc(ip, 1, whichfork);
                ep = ifp->if_u1.if_extents;
@@ -3413,8 +3428,10 @@ xfs_bmap_local_to_extents(
                XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip,
                        XFS_TRANS_DQ_BCOUNT, 1L);
                flags |= XFS_ILOG_FEXT(whichfork);
-       } else
+       } else {
                ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
+               xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork);
+       }
        ifp->if_flags &= ~XFS_IFINLINE;
        ifp->if_flags |= XFS_IFEXTENTS;
        XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
@@ -3796,22 +3813,24 @@ xfs_bunmap_trace(
 int                                            /* error code */
 xfs_bmap_add_attrfork(
        xfs_inode_t             *ip,            /* incore inode pointer */
-       int                     rsvd)           /* OK to allocated reserved blocks in trans */
+       int                     size,           /* space new attribute needs */
+       int                     rsvd)           /* xact may use reserved blks */
 {
-       int                     blks;           /* space reservation */
-       int                     committed;      /* xaction was committed */
-       int                     error;          /* error return value */
        xfs_fsblock_t           firstblock;     /* 1st block/ag allocated */
        xfs_bmap_free_t         flist;          /* freed extent list */
-       int                     logflags;       /* logging flags */
        xfs_mount_t             *mp;            /* mount structure */
-       unsigned long           s;              /* spinlock spl value */
        xfs_trans_t             *tp;            /* transaction pointer */
+       unsigned long           s;              /* spinlock spl value */
+       int                     blks;           /* space reservation */
+       int                     version = 1;    /* superblock attr version */
+       int                     committed;      /* xaction was committed */
+       int                     logflags;       /* logging flags */
+       int                     error;          /* error return value */
 
+       ASSERT(XFS_IFORK_Q(ip) == 0);
        ASSERT(ip->i_df.if_ext_max ==
               XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
-       if (XFS_IFORK_Q(ip))
-               return 0;
+
        mp = ip->i_mount;
        ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
        tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK);
@@ -3853,7 +3872,11 @@ xfs_bmap_add_attrfork(
        case XFS_DINODE_FMT_LOCAL:
        case XFS_DINODE_FMT_EXTENTS:
        case XFS_DINODE_FMT_BTREE:
-               ip->i_d.di_forkoff = mp->m_attroffset >> 3;
+               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;
+               else if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR))
+                       version = 2;
                break;
        default:
                ASSERT(0);
@@ -3890,12 +3913,22 @@ xfs_bmap_add_attrfork(
                xfs_trans_log_inode(tp, ip, logflags);
        if (error)
                goto error2;
-       if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) {
+       if (!XFS_SB_VERSION_HASATTR(&mp->m_sb) ||
+          (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) {
+               __int64_t sbfields = 0;
+
                s = XFS_SB_LOCK(mp);
                if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) {
                        XFS_SB_VERSION_ADDATTR(&mp->m_sb);
+                       sbfields |= XFS_SB_VERSIONNUM;
+               }
+               if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2) {
+                       XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
+                       sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
+               }
+               if (sbfields) {
                        XFS_SB_UNLOCK(mp, s);
-                       xfs_mod_sb(tp, XFS_SB_VERSIONNUM);
+                       xfs_mod_sb(tp, sbfields);
                } else
                        XFS_SB_UNLOCK(mp, s);
        }
@@ -3988,13 +4021,19 @@ xfs_bmap_compute_maxlevels(
         * (a signed 32-bit number, xfs_extnum_t), or by di_anextents
         * (a signed 16-bit number, xfs_aextnum_t).
         */
-       maxleafents = (whichfork == XFS_DATA_FORK) ? MAXEXTNUM : MAXAEXTNUM;
+       if (whichfork == XFS_DATA_FORK) {
+               maxleafents = MAXEXTNUM;
+               sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
+                       mp->m_attroffset : XFS_BMDR_SPACE_CALC(MINDBTPTRS);
+       } else {
+               maxleafents = MAXAEXTNUM;
+               sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
+                       mp->m_sb.sb_inodesize - mp->m_attroffset :
+                       XFS_BMDR_SPACE_CALC(MINABTPTRS);
+       }
+       maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
        minleafrecs = mp->m_bmap_dmnr[0];
        minnoderecs = mp->m_bmap_dmnr[1];
-       sz = (whichfork == XFS_DATA_FORK) ?
-               mp->m_attroffset :
-               mp->m_sb.sb_inodesize - mp->m_attroffset;
-       maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
        maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
        for (level = 1; maxblocks > 1; level++) {
                if (maxblocks <= maxrootrecs)
@@ -4332,8 +4371,8 @@ xfs_bmap_read_extents(
        /*
         * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
         */
-       ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0);
-       level = INT_GET(block->bb_level, ARCH_CONVERT);
+       level = be16_to_cpu(block->bb_level);
+       ASSERT(level > 0);
        pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
        ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
        ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
@@ -4376,7 +4415,7 @@ xfs_bmap_read_extents(
                xfs_extnum_t    num_recs;
 
 
-               num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+               num_recs = be16_to_cpu(block->bb_numrecs);
                if (unlikely(i + num_recs > room)) {
                        ASSERT(i + num_recs <= room);
                        xfs_fs_cmn_err(CE_WARN, ip->i_mount,
@@ -4393,7 +4432,7 @@ xfs_bmap_read_extents(
                /*
                 * Read-ahead the next leaf block, if any.
                 */
-               nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
+               nextbno = be64_to_cpu(block->bb_rightsib);
                if (nextbno != NULLFSBLOCK)
                        xfs_btree_reada_bufl(mp, nextbno, 1);
                /*
@@ -4650,7 +4689,7 @@ xfs_bmapi(
        }
        if (wr && *firstblock == NULLFSBLOCK) {
                if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
-                       minleft = INT_GET(ifp->if_broot->bb_level, ARCH_CONVERT) + 1;
+                       minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
                else
                        minleft = 1;
        } else
@@ -4754,10 +4793,20 @@ xfs_bmapi(
                                        error = xfs_mod_incore_sb(mp,
                                                        XFS_SBS_FDBLOCKS,
                                                        -(alen), rsvd);
-                               if (!error)
+                               if (!error) {
                                        error = xfs_mod_incore_sb(mp,
                                                        XFS_SBS_FDBLOCKS,
                                                        -(indlen), rsvd);
+                                       if (error && rt) {
+                                               xfs_mod_incore_sb(ip->i_mount,
+                                                       XFS_SBS_FREXTENTS,
+                                                       extsz, rsvd);
+                                       } else if (error) {
+                                               xfs_mod_incore_sb(ip->i_mount,
+                                                       XFS_SBS_FDBLOCKS,
+                                                       alen, rsvd);
+                                       }
+                               }
 
                                if (error) {
                                        if (XFS_IS_QUOTA_ON(ip->i_mount))
@@ -5682,12 +5731,13 @@ xfs_getbmap(
                        out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff);
                        out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
                        ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
-                       if (prealloced &&
-                           map[i].br_startblock == HOLESTARTBLOCK &&
-                           out.bmv_offset + out.bmv_length == bmvend) {
-                               /*
-                                * came to hole at end of file
-                                */
+                        if (map[i].br_startblock == HOLESTARTBLOCK &&
+                           ((prealloced && out.bmv_offset + out.bmv_length == bmvend) ||
+                             whichfork == XFS_ATTR_FORK )) {
+                                /*
+                                 * came to hole at end of file or the end of
+                                   attribute fork
+                                 */
                                goto unlock_and_return;
                        } else {
                                out.bmv_block =
@@ -5917,10 +5967,10 @@ xfs_check_block(
        xfs_bmbt_ptr_t          *pp, *thispa;   /* pointer to block address */
        xfs_bmbt_key_t          *prevp, *keyp;
 
-       ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0);
+       ASSERT(be16_to_cpu(block->bb_level) > 0);
 
        prevp = NULL;
-       for( i = 1; i <= INT_GET(block->bb_numrecs, ARCH_CONVERT);i++) {
+       for( i = 1; i <= be16_to_cpu(block->bb_numrecs); i++) {
                dmxr = mp->m_bmap_dmxr[0];
 
                if (root) {
@@ -5945,7 +5995,7 @@ xfs_check_block(
                        pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
                                xfs_bmbt, block, i, dmxr);
                }
-               for (j = i+1; j <= INT_GET(block->bb_numrecs, ARCH_CONVERT); j++) {
+               for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) {
                        if (root) {
                                thispa = XFS_BMAP_BROOT_PTR_ADDR(block, j, sz);
                        } else {
@@ -5998,8 +6048,8 @@ xfs_bmap_check_leaf_extents(
        /*
         * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
         */
-       ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0);
-       level = INT_GET(block->bb_level, ARCH_CONVERT);
+       level = be16_to_cpu(block->bb_level);
+       ASSERT(level > 0);
        xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
        pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
        ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
@@ -6059,13 +6109,13 @@ xfs_bmap_check_leaf_extents(
                xfs_extnum_t    num_recs;
 
 
-               num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+               num_recs = be16_to_cpu(block->bb_numrecs);
 
                /*
                 * Read-ahead the next leaf block, if any.
                 */
 
-               nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
+               nextbno = be64_to_cpu(block->bb_rightsib);
 
                /*
                 * Check all the extents to make sure they are OK.
@@ -6121,7 +6171,7 @@ error0:
                xfs_trans_brelse(NULL, bp);
 error_norelse:
        cmn_err(CE_WARN, "%s: BAD after btree leaves for %d extents",
-               i, __FUNCTION__);
+               __FUNCTION__, i);
        panic("%s: CORRUPTED BTREE OR SOMETHING", __FUNCTION__);
        return;
 }
@@ -6162,8 +6212,8 @@ xfs_bmap_count_blocks(
         * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
         */
        block = ifp->if_broot;
-       ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0);
-       level = INT_GET(block->bb_level, ARCH_CONVERT);
+       level = be16_to_cpu(block->bb_level);
+       ASSERT(level > 0);
        pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
        ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
        ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
@@ -6208,14 +6258,14 @@ xfs_bmap_count_tree(
 
        if (--level) {
                /* Not at node above leafs, count this level of nodes */
-               nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
+               nextbno = be64_to_cpu(block->bb_rightsib);
                while (nextbno != NULLFSBLOCK) {
                        if ((error = xfs_btree_read_bufl(mp, tp, nextbno,
                                0, &nbp, XFS_BMAP_BTREE_REF)))
                                return error;
                        *count += 1;
                        nextblock = XFS_BUF_TO_BMBT_BLOCK(nbp);
-                       nextbno = INT_GET(nextblock->bb_rightsib, ARCH_CONVERT);
+                       nextbno = be64_to_cpu(nextblock->bb_rightsib);
                        xfs_trans_brelse(tp, nbp);
                }
 
@@ -6234,11 +6284,11 @@ xfs_bmap_count_tree(
        } else {
                /* count all level 1 nodes and their leaves */
                for (;;) {
-                       nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
-                       numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+                       nextbno = be64_to_cpu(block->bb_rightsib);
+                       numrecs = be16_to_cpu(block->bb_numrecs);
                        frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize,
                                xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]);
-                       if (unlikely(xfs_bmap_count_leaves(frp, numrecs, count) < 0)) {
+                       if (unlikely(xfs_bmap_disk_count_leaves(frp, numrecs, count) < 0)) {
                                xfs_trans_brelse(tp, bp);
                                XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
                                                 XFS_ERRLEVEL_LOW, mp);
@@ -6269,6 +6319,22 @@ xfs_bmap_count_leaves(
 {
        int             b;
 
+       for ( b = 1; b <= numrecs; b++, frp++)
+               *count += xfs_bmbt_get_blockcount(frp);
+       return 0;
+}
+
+/*
+ * Count leaf blocks given a pointer to an extent list originally in btree format.
+ */
+int
+xfs_bmap_disk_count_leaves(
+       xfs_bmbt_rec_t          *frp,
+       int                     numrecs,
+       int                     *count)
+{
+       int             b;
+
        for ( b = 1; b <= numrecs; b++, frp++)
                *count += xfs_bmbt_disk_get_blockcount(frp);
        return 0;