aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c244
1 files changed, 150 insertions, 94 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 3e76def1283d..e415a4698e9c 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -1,68 +1,53 @@
1/* 1/*
2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or
5 * under the terms of version 2 of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
7 * 8 *
8 * This program is distributed in the hope that it would be useful, but 9 * This program is distributed in the hope that it would be useful,
9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
11 * 13 *
12 * Further, this software is distributed without any warranty that it is 14 * You should have received a copy of the GNU General Public License
13 * free of the rightful claim of any third person regarding infringement 15 * along with this program; if not, write the Free Software Foundation,
14 * or the like. Any license provided herein, whether implied or 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */ 17 */
32
33#include "xfs.h" 18#include "xfs.h"
34 19#include "xfs_fs.h"
35#include "xfs_macros.h"
36#include "xfs_types.h" 20#include "xfs_types.h"
37#include "xfs_inum.h" 21#include "xfs_bit.h"
38#include "xfs_log.h" 22#include "xfs_log.h"
23#include "xfs_inum.h"
39#include "xfs_trans.h" 24#include "xfs_trans.h"
40#include "xfs_sb.h" 25#include "xfs_sb.h"
41#include "xfs_ag.h" 26#include "xfs_ag.h"
42#include "xfs_dir.h" 27#include "xfs_dir.h"
43#include "xfs_dir2.h" 28#include "xfs_dir2.h"
44#include "xfs_dmapi.h" 29#include "xfs_da_btree.h"
45#include "xfs_mount.h"
46#include "xfs_alloc_btree.h"
47#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h"
48#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
49#include "xfs_btree.h"
50#include "xfs_ialloc.h"
51#include "xfs_attr_sf.h"
52#include "xfs_dir_sf.h" 33#include "xfs_dir_sf.h"
53#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h"
54#include "xfs_dinode.h" 36#include "xfs_dinode.h"
55#include "xfs_inode_item.h"
56#include "xfs_inode.h" 37#include "xfs_inode.h"
38#include "xfs_btree.h"
39#include "xfs_dmapi.h"
40#include "xfs_mount.h"
41#include "xfs_ialloc.h"
57#include "xfs_itable.h" 42#include "xfs_itable.h"
43#include "xfs_inode_item.h"
58#include "xfs_extfree_item.h" 44#include "xfs_extfree_item.h"
59#include "xfs_alloc.h" 45#include "xfs_alloc.h"
60#include "xfs_bmap.h" 46#include "xfs_bmap.h"
61#include "xfs_rtalloc.h" 47#include "xfs_rtalloc.h"
62#include "xfs_error.h" 48#include "xfs_error.h"
63#include "xfs_da_btree.h"
64#include "xfs_dir_leaf.h" 49#include "xfs_dir_leaf.h"
65#include "xfs_bit.h" 50#include "xfs_attr_leaf.h"
66#include "xfs_rw.h" 51#include "xfs_rw.h"
67#include "xfs_quota.h" 52#include "xfs_quota.h"
68#include "xfs_trans_space.h" 53#include "xfs_trans_space.h"
@@ -438,6 +423,12 @@ xfs_bmap_count_leaves(
438 int numrecs, 423 int numrecs,
439 int *count); 424 int *count);
440 425
426STATIC int
427xfs_bmap_disk_count_leaves(
428 xfs_bmbt_rec_t *frp,
429 int numrecs,
430 int *count);
431
441/* 432/*
442 * Bmap internal routines. 433 * Bmap internal routines.
443 */ 434 */
@@ -2772,8 +2763,8 @@ xfs_bmap_btree_to_extents(
2772 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 2763 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
2773 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); 2764 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
2774 rblock = ifp->if_broot; 2765 rblock = ifp->if_broot;
2775 ASSERT(INT_GET(rblock->bb_level, ARCH_CONVERT) == 1); 2766 ASSERT(be16_to_cpu(rblock->bb_level) == 1);
2776 ASSERT(INT_GET(rblock->bb_numrecs, ARCH_CONVERT) == 1); 2767 ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1);
2777 ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1); 2768 ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1);
2778 mp = ip->i_mount; 2769 mp = ip->i_mount;
2779 pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes); 2770 pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes);
@@ -3216,11 +3207,11 @@ xfs_bmap_extents_to_btree(
3216 * Fill in the root. 3207 * Fill in the root.
3217 */ 3208 */
3218 block = ifp->if_broot; 3209 block = ifp->if_broot;
3219 INT_SET(block->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC); 3210 block->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
3220 INT_SET(block->bb_level, ARCH_CONVERT, 1); 3211 block->bb_level = cpu_to_be16(1);
3221 INT_SET(block->bb_numrecs, ARCH_CONVERT, 1); 3212 block->bb_numrecs = cpu_to_be16(1);
3222 INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLDFSBNO); 3213 block->bb_leftsib = cpu_to_be64(NULLDFSBNO);
3223 INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLDFSBNO); 3214 block->bb_rightsib = cpu_to_be64(NULLDFSBNO);
3224 /* 3215 /*
3225 * Need a cursor. Can't allocate until bb_level is filled in. 3216 * Need a cursor. Can't allocate until bb_level is filled in.
3226 */ 3217 */
@@ -3273,10 +3264,10 @@ xfs_bmap_extents_to_btree(
3273 * Fill in the child block. 3264 * Fill in the child block.
3274 */ 3265 */
3275 ablock = XFS_BUF_TO_BMBT_BLOCK(abp); 3266 ablock = XFS_BUF_TO_BMBT_BLOCK(abp);
3276 INT_SET(ablock->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC); 3267 ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
3277 ablock->bb_level = 0; 3268 ablock->bb_level = 0;
3278 INT_SET(ablock->bb_leftsib, ARCH_CONVERT, NULLDFSBNO); 3269 ablock->bb_leftsib = cpu_to_be64(NULLDFSBNO);
3279 INT_SET(ablock->bb_rightsib, ARCH_CONVERT, NULLDFSBNO); 3270 ablock->bb_rightsib = cpu_to_be64(NULLDFSBNO);
3280 arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); 3271 arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
3281 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3272 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3282 for (ep = ifp->if_u1.if_extents, cnt = i = 0; i < nextents; i++, ep++) { 3273 for (ep = ifp->if_u1.if_extents, cnt = i = 0; i < nextents; i++, ep++) {
@@ -3286,8 +3277,8 @@ xfs_bmap_extents_to_btree(
3286 arp++; cnt++; 3277 arp++; cnt++;
3287 } 3278 }
3288 } 3279 }
3289 INT_SET(ablock->bb_numrecs, ARCH_CONVERT, cnt); 3280 ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork));
3290 ASSERT(INT_GET(ablock->bb_numrecs, ARCH_CONVERT) == XFS_IFORK_NEXTENTS(ip, whichfork)); 3281 ablock->bb_numrecs = cpu_to_be16(cnt);
3291 /* 3282 /*
3292 * Fill in the root key and pointer. 3283 * Fill in the root key and pointer.
3293 */ 3284 */
@@ -3301,7 +3292,7 @@ xfs_bmap_extents_to_btree(
3301 * the root is at the right level. 3292 * the root is at the right level.
3302 */ 3293 */
3303 xfs_bmbt_log_block(cur, abp, XFS_BB_ALL_BITS); 3294 xfs_bmbt_log_block(cur, abp, XFS_BB_ALL_BITS);
3304 xfs_bmbt_log_recs(cur, abp, 1, INT_GET(ablock->bb_numrecs, ARCH_CONVERT)); 3295 xfs_bmbt_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
3305 ASSERT(*curp == NULL); 3296 ASSERT(*curp == NULL);
3306 *curp = cur; 3297 *curp = cur;
3307 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FBROOT(whichfork); 3298 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FBROOT(whichfork);
@@ -3337,6 +3328,29 @@ xfs_bmap_insert_exlist(
3337} 3328}
3338 3329
3339/* 3330/*
3331 * Helper routine to reset inode di_forkoff field when switching
3332 * attribute fork from local to extent format - we reset it where
3333 * possible to make space available for inline data fork extents.
3334 */
3335STATIC void
3336xfs_bmap_forkoff_reset(
3337 xfs_mount_t *mp,
3338 xfs_inode_t *ip,
3339 int whichfork)
3340{
3341 if (whichfork == XFS_ATTR_FORK &&
3342 (ip->i_d.di_format != XFS_DINODE_FMT_DEV) &&
3343 (ip->i_d.di_format != XFS_DINODE_FMT_UUID) &&
3344 ((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) {
3345 ip->i_d.di_forkoff = mp->m_attroffset >> 3;
3346 ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) /
3347 (uint)sizeof(xfs_bmbt_rec_t);
3348 ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) /
3349 (uint)sizeof(xfs_bmbt_rec_t);
3350 }
3351}
3352
3353/*
3340 * Convert a local file to an extents file. 3354 * Convert a local file to an extents file.
3341 * This code is out of bounds for data forks of regular files, 3355 * This code is out of bounds for data forks of regular files,
3342 * since the file data needs to get logged so things will stay consistent. 3356 * since the file data needs to get logged so things will stay consistent.
@@ -3403,6 +3417,7 @@ xfs_bmap_local_to_extents(
3403 memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data, 3417 memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data,
3404 ifp->if_bytes); 3418 ifp->if_bytes);
3405 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); 3419 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
3420 xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
3406 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); 3421 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
3407 xfs_iext_realloc(ip, 1, whichfork); 3422 xfs_iext_realloc(ip, 1, whichfork);
3408 ep = ifp->if_u1.if_extents; 3423 ep = ifp->if_u1.if_extents;
@@ -3413,8 +3428,10 @@ xfs_bmap_local_to_extents(
3413 XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip, 3428 XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip,
3414 XFS_TRANS_DQ_BCOUNT, 1L); 3429 XFS_TRANS_DQ_BCOUNT, 1L);
3415 flags |= XFS_ILOG_FEXT(whichfork); 3430 flags |= XFS_ILOG_FEXT(whichfork);
3416 } else 3431 } else {
3417 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); 3432 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
3433 xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork);
3434 }
3418 ifp->if_flags &= ~XFS_IFINLINE; 3435 ifp->if_flags &= ~XFS_IFINLINE;
3419 ifp->if_flags |= XFS_IFEXTENTS; 3436 ifp->if_flags |= XFS_IFEXTENTS;
3420 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); 3437 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
@@ -3796,22 +3813,24 @@ xfs_bunmap_trace(
3796int /* error code */ 3813int /* error code */
3797xfs_bmap_add_attrfork( 3814xfs_bmap_add_attrfork(
3798 xfs_inode_t *ip, /* incore inode pointer */ 3815 xfs_inode_t *ip, /* incore inode pointer */
3799 int rsvd) /* OK to allocated reserved blocks in trans */ 3816 int size, /* space new attribute needs */
3817 int rsvd) /* xact may use reserved blks */
3800{ 3818{
3801 int blks; /* space reservation */
3802 int committed; /* xaction was committed */
3803 int error; /* error return value */
3804 xfs_fsblock_t firstblock; /* 1st block/ag allocated */ 3819 xfs_fsblock_t firstblock; /* 1st block/ag allocated */
3805 xfs_bmap_free_t flist; /* freed extent list */ 3820 xfs_bmap_free_t flist; /* freed extent list */
3806 int logflags; /* logging flags */
3807 xfs_mount_t *mp; /* mount structure */ 3821 xfs_mount_t *mp; /* mount structure */
3808 unsigned long s; /* spinlock spl value */
3809 xfs_trans_t *tp; /* transaction pointer */ 3822 xfs_trans_t *tp; /* transaction pointer */
3823 unsigned long s; /* spinlock spl value */
3824 int blks; /* space reservation */
3825 int version = 1; /* superblock attr version */
3826 int committed; /* xaction was committed */
3827 int logflags; /* logging flags */
3828 int error; /* error return value */
3810 3829
3830 ASSERT(XFS_IFORK_Q(ip) == 0);
3811 ASSERT(ip->i_df.if_ext_max == 3831 ASSERT(ip->i_df.if_ext_max ==
3812 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); 3832 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
3813 if (XFS_IFORK_Q(ip)) 3833
3814 return 0;
3815 mp = ip->i_mount; 3834 mp = ip->i_mount;
3816 ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); 3835 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
3817 tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK); 3836 tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK);
@@ -3853,7 +3872,11 @@ xfs_bmap_add_attrfork(
3853 case XFS_DINODE_FMT_LOCAL: 3872 case XFS_DINODE_FMT_LOCAL:
3854 case XFS_DINODE_FMT_EXTENTS: 3873 case XFS_DINODE_FMT_EXTENTS:
3855 case XFS_DINODE_FMT_BTREE: 3874 case XFS_DINODE_FMT_BTREE:
3856 ip->i_d.di_forkoff = mp->m_attroffset >> 3; 3875 ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
3876 if (!ip->i_d.di_forkoff)
3877 ip->i_d.di_forkoff = mp->m_attroffset >> 3;
3878 else if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR))
3879 version = 2;
3857 break; 3880 break;
3858 default: 3881 default:
3859 ASSERT(0); 3882 ASSERT(0);
@@ -3890,12 +3913,22 @@ xfs_bmap_add_attrfork(
3890 xfs_trans_log_inode(tp, ip, logflags); 3913 xfs_trans_log_inode(tp, ip, logflags);
3891 if (error) 3914 if (error)
3892 goto error2; 3915 goto error2;
3893 if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) { 3916 if (!XFS_SB_VERSION_HASATTR(&mp->m_sb) ||
3917 (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) {
3918 __int64_t sbfields = 0;
3919
3894 s = XFS_SB_LOCK(mp); 3920 s = XFS_SB_LOCK(mp);
3895 if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) { 3921 if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) {
3896 XFS_SB_VERSION_ADDATTR(&mp->m_sb); 3922 XFS_SB_VERSION_ADDATTR(&mp->m_sb);
3923 sbfields |= XFS_SB_VERSIONNUM;
3924 }
3925 if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2) {
3926 XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
3927 sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
3928 }
3929 if (sbfields) {
3897 XFS_SB_UNLOCK(mp, s); 3930 XFS_SB_UNLOCK(mp, s);
3898 xfs_mod_sb(tp, XFS_SB_VERSIONNUM); 3931 xfs_mod_sb(tp, sbfields);
3899 } else 3932 } else
3900 XFS_SB_UNLOCK(mp, s); 3933 XFS_SB_UNLOCK(mp, s);
3901 } 3934 }
@@ -3988,13 +4021,19 @@ xfs_bmap_compute_maxlevels(
3988 * (a signed 32-bit number, xfs_extnum_t), or by di_anextents 4021 * (a signed 32-bit number, xfs_extnum_t), or by di_anextents
3989 * (a signed 16-bit number, xfs_aextnum_t). 4022 * (a signed 16-bit number, xfs_aextnum_t).
3990 */ 4023 */
3991 maxleafents = (whichfork == XFS_DATA_FORK) ? MAXEXTNUM : MAXAEXTNUM; 4024 if (whichfork == XFS_DATA_FORK) {
4025 maxleafents = MAXEXTNUM;
4026 sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
4027 mp->m_attroffset : XFS_BMDR_SPACE_CALC(MINDBTPTRS);
4028 } else {
4029 maxleafents = MAXAEXTNUM;
4030 sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
4031 mp->m_sb.sb_inodesize - mp->m_attroffset :
4032 XFS_BMDR_SPACE_CALC(MINABTPTRS);
4033 }
4034 maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
3992 minleafrecs = mp->m_bmap_dmnr[0]; 4035 minleafrecs = mp->m_bmap_dmnr[0];
3993 minnoderecs = mp->m_bmap_dmnr[1]; 4036 minnoderecs = mp->m_bmap_dmnr[1];
3994 sz = (whichfork == XFS_DATA_FORK) ?
3995 mp->m_attroffset :
3996 mp->m_sb.sb_inodesize - mp->m_attroffset;
3997 maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
3998 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; 4037 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
3999 for (level = 1; maxblocks > 1; level++) { 4038 for (level = 1; maxblocks > 1; level++) {
4000 if (maxblocks <= maxrootrecs) 4039 if (maxblocks <= maxrootrecs)
@@ -4332,8 +4371,8 @@ xfs_bmap_read_extents(
4332 /* 4371 /*
4333 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. 4372 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
4334 */ 4373 */
4335 ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); 4374 level = be16_to_cpu(block->bb_level);
4336 level = INT_GET(block->bb_level, ARCH_CONVERT); 4375 ASSERT(level > 0);
4337 pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); 4376 pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
4338 ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); 4377 ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
4339 ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); 4378 ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
@@ -4376,7 +4415,7 @@ xfs_bmap_read_extents(
4376 xfs_extnum_t num_recs; 4415 xfs_extnum_t num_recs;
4377 4416
4378 4417
4379 num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT); 4418 num_recs = be16_to_cpu(block->bb_numrecs);
4380 if (unlikely(i + num_recs > room)) { 4419 if (unlikely(i + num_recs > room)) {
4381 ASSERT(i + num_recs <= room); 4420 ASSERT(i + num_recs <= room);
4382 xfs_fs_cmn_err(CE_WARN, ip->i_mount, 4421 xfs_fs_cmn_err(CE_WARN, ip->i_mount,
@@ -4393,7 +4432,7 @@ xfs_bmap_read_extents(
4393 /* 4432 /*
4394 * Read-ahead the next leaf block, if any. 4433 * Read-ahead the next leaf block, if any.
4395 */ 4434 */
4396 nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT); 4435 nextbno = be64_to_cpu(block->bb_rightsib);
4397 if (nextbno != NULLFSBLOCK) 4436 if (nextbno != NULLFSBLOCK)
4398 xfs_btree_reada_bufl(mp, nextbno, 1); 4437 xfs_btree_reada_bufl(mp, nextbno, 1);
4399 /* 4438 /*
@@ -4650,7 +4689,7 @@ xfs_bmapi(
4650 } 4689 }
4651 if (wr && *firstblock == NULLFSBLOCK) { 4690 if (wr && *firstblock == NULLFSBLOCK) {
4652 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) 4691 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
4653 minleft = INT_GET(ifp->if_broot->bb_level, ARCH_CONVERT) + 1; 4692 minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
4654 else 4693 else
4655 minleft = 1; 4694 minleft = 1;
4656 } else 4695 } else
@@ -5692,12 +5731,13 @@ xfs_getbmap(
5692 out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff); 5731 out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff);
5693 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount); 5732 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
5694 ASSERT(map[i].br_startblock != DELAYSTARTBLOCK); 5733 ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
5695 if (prealloced && 5734 if (map[i].br_startblock == HOLESTARTBLOCK &&
5696 map[i].br_startblock == HOLESTARTBLOCK && 5735 ((prealloced && out.bmv_offset + out.bmv_length == bmvend) ||
5697 out.bmv_offset + out.bmv_length == bmvend) { 5736 whichfork == XFS_ATTR_FORK )) {
5698 /* 5737 /*
5699 * came to hole at end of file 5738 * came to hole at end of file or the end of
5700 */ 5739 attribute fork
5740 */
5701 goto unlock_and_return; 5741 goto unlock_and_return;
5702 } else { 5742 } else {
5703 out.bmv_block = 5743 out.bmv_block =
@@ -5927,10 +5967,10 @@ xfs_check_block(
5927 xfs_bmbt_ptr_t *pp, *thispa; /* pointer to block address */ 5967 xfs_bmbt_ptr_t *pp, *thispa; /* pointer to block address */
5928 xfs_bmbt_key_t *prevp, *keyp; 5968 xfs_bmbt_key_t *prevp, *keyp;
5929 5969
5930 ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); 5970 ASSERT(be16_to_cpu(block->bb_level) > 0);
5931 5971
5932 prevp = NULL; 5972 prevp = NULL;
5933 for( i = 1; i <= INT_GET(block->bb_numrecs, ARCH_CONVERT);i++) { 5973 for( i = 1; i <= be16_to_cpu(block->bb_numrecs); i++) {
5934 dmxr = mp->m_bmap_dmxr[0]; 5974 dmxr = mp->m_bmap_dmxr[0];
5935 5975
5936 if (root) { 5976 if (root) {
@@ -5955,7 +5995,7 @@ xfs_check_block(
5955 pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, 5995 pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
5956 xfs_bmbt, block, i, dmxr); 5996 xfs_bmbt, block, i, dmxr);
5957 } 5997 }
5958 for (j = i+1; j <= INT_GET(block->bb_numrecs, ARCH_CONVERT); j++) { 5998 for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) {
5959 if (root) { 5999 if (root) {
5960 thispa = XFS_BMAP_BROOT_PTR_ADDR(block, j, sz); 6000 thispa = XFS_BMAP_BROOT_PTR_ADDR(block, j, sz);
5961 } else { 6001 } else {
@@ -6008,8 +6048,8 @@ xfs_bmap_check_leaf_extents(
6008 /* 6048 /*
6009 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. 6049 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
6010 */ 6050 */
6011 ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); 6051 level = be16_to_cpu(block->bb_level);
6012 level = INT_GET(block->bb_level, ARCH_CONVERT); 6052 ASSERT(level > 0);
6013 xfs_check_block(block, mp, 1, ifp->if_broot_bytes); 6053 xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
6014 pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); 6054 pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
6015 ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); 6055 ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
@@ -6069,13 +6109,13 @@ xfs_bmap_check_leaf_extents(
6069 xfs_extnum_t num_recs; 6109 xfs_extnum_t num_recs;
6070 6110
6071 6111
6072 num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT); 6112 num_recs = be16_to_cpu(block->bb_numrecs);
6073 6113
6074 /* 6114 /*
6075 * Read-ahead the next leaf block, if any. 6115 * Read-ahead the next leaf block, if any.
6076 */ 6116 */
6077 6117
6078 nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT); 6118 nextbno = be64_to_cpu(block->bb_rightsib);
6079 6119
6080 /* 6120 /*
6081 * Check all the extents to make sure they are OK. 6121 * Check all the extents to make sure they are OK.
@@ -6131,7 +6171,7 @@ error0:
6131 xfs_trans_brelse(NULL, bp); 6171 xfs_trans_brelse(NULL, bp);
6132error_norelse: 6172error_norelse:
6133 cmn_err(CE_WARN, "%s: BAD after btree leaves for %d extents", 6173 cmn_err(CE_WARN, "%s: BAD after btree leaves for %d extents",
6134 i, __FUNCTION__); 6174 __FUNCTION__, i);
6135 panic("%s: CORRUPTED BTREE OR SOMETHING", __FUNCTION__); 6175 panic("%s: CORRUPTED BTREE OR SOMETHING", __FUNCTION__);
6136 return; 6176 return;
6137} 6177}
@@ -6172,8 +6212,8 @@ xfs_bmap_count_blocks(
6172 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. 6212 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
6173 */ 6213 */
6174 block = ifp->if_broot; 6214 block = ifp->if_broot;
6175 ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); 6215 level = be16_to_cpu(block->bb_level);
6176 level = INT_GET(block->bb_level, ARCH_CONVERT); 6216 ASSERT(level > 0);
6177 pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); 6217 pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
6178 ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); 6218 ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
6179 ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); 6219 ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
@@ -6218,14 +6258,14 @@ xfs_bmap_count_tree(
6218 6258
6219 if (--level) { 6259 if (--level) {
6220 /* Not at node above leafs, count this level of nodes */ 6260 /* Not at node above leafs, count this level of nodes */
6221 nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT); 6261 nextbno = be64_to_cpu(block->bb_rightsib);
6222 while (nextbno != NULLFSBLOCK) { 6262 while (nextbno != NULLFSBLOCK) {
6223 if ((error = xfs_btree_read_bufl(mp, tp, nextbno, 6263 if ((error = xfs_btree_read_bufl(mp, tp, nextbno,
6224 0, &nbp, XFS_BMAP_BTREE_REF))) 6264 0, &nbp, XFS_BMAP_BTREE_REF)))
6225 return error; 6265 return error;
6226 *count += 1; 6266 *count += 1;
6227 nextblock = XFS_BUF_TO_BMBT_BLOCK(nbp); 6267 nextblock = XFS_BUF_TO_BMBT_BLOCK(nbp);
6228 nextbno = INT_GET(nextblock->bb_rightsib, ARCH_CONVERT); 6268 nextbno = be64_to_cpu(nextblock->bb_rightsib);
6229 xfs_trans_brelse(tp, nbp); 6269 xfs_trans_brelse(tp, nbp);
6230 } 6270 }
6231 6271
@@ -6244,11 +6284,11 @@ xfs_bmap_count_tree(
6244 } else { 6284 } else {
6245 /* count all level 1 nodes and their leaves */ 6285 /* count all level 1 nodes and their leaves */
6246 for (;;) { 6286 for (;;) {
6247 nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT); 6287 nextbno = be64_to_cpu(block->bb_rightsib);
6248 numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT); 6288 numrecs = be16_to_cpu(block->bb_numrecs);
6249 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, 6289 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize,
6250 xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]); 6290 xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]);
6251 if (unlikely(xfs_bmap_count_leaves(frp, numrecs, count) < 0)) { 6291 if (unlikely(xfs_bmap_disk_count_leaves(frp, numrecs, count) < 0)) {
6252 xfs_trans_brelse(tp, bp); 6292 xfs_trans_brelse(tp, bp);
6253 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)", 6293 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
6254 XFS_ERRLEVEL_LOW, mp); 6294 XFS_ERRLEVEL_LOW, mp);
@@ -6280,6 +6320,22 @@ xfs_bmap_count_leaves(
6280 int b; 6320 int b;
6281 6321
6282 for ( b = 1; b <= numrecs; b++, frp++) 6322 for ( b = 1; b <= numrecs; b++, frp++)
6323 *count += xfs_bmbt_get_blockcount(frp);
6324 return 0;
6325}
6326
6327/*
6328 * Count leaf blocks given a pointer to an extent list originally in btree format.
6329 */
6330int
6331xfs_bmap_disk_count_leaves(
6332 xfs_bmbt_rec_t *frp,
6333 int numrecs,
6334 int *count)
6335{
6336 int b;
6337
6338 for ( b = 1; b <= numrecs; b++, frp++)
6283 *count += xfs_bmbt_disk_get_blockcount(frp); 6339 *count += xfs_bmbt_disk_get_blockcount(frp);
6284 return 0; 6340 return 0;
6285} 6341}