]> err.no Git - linux-2.6/blobdiff - fs/xfs/xfs_bmap.c
Merge master.kernel.org:/home/rmk/linux-2.6-serial
[linux-2.6] / fs / xfs / xfs_bmap.c
index 82496d901d23853613d174c6a11bde97979aaabb..e415a4698e9c3e30836f5c2578f40f2f921592c0 100644 (file)
@@ -423,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.
  */
@@ -2757,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);
@@ -3201,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.
         */
@@ -3258,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++) {
@@ -3271,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.
         */
@@ -3286,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);
@@ -3909,19 +3915,20 @@ xfs_bmap_add_attrfork(
                goto error2;
        if (!XFS_SB_VERSION_HASATTR(&mp->m_sb) ||
           (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) {
-               logflags = 0;
+               __int64_t sbfields = 0;
+
                s = XFS_SB_LOCK(mp);
                if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) {
                        XFS_SB_VERSION_ADDATTR(&mp->m_sb);
-                       logflags |= XFS_SB_VERSIONNUM;
+                       sbfields |= XFS_SB_VERSIONNUM;
                }
                if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2) {
                        XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
-                       logflags |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
+                       sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
                }
-               if (logflags) {
+               if (sbfields) {
                        XFS_SB_UNLOCK(mp, s);
-                       xfs_mod_sb(tp, logflags);
+                       xfs_mod_sb(tp, sbfields);
                } else
                        XFS_SB_UNLOCK(mp, s);
        }
@@ -4364,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);
@@ -4408,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,
@@ -4425,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);
                /*
@@ -4682,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
@@ -5724,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 =
@@ -5959,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) {
@@ -5987,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 {
@@ -6040,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);
@@ -6101,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.
@@ -6204,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);
@@ -6250,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);
                }
 
@@ -6276,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);
@@ -6311,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;