diff options
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r-- | fs/xfs/xfs_bmap.c | 244 |
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 | ||
426 | STATIC int | ||
427 | xfs_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 | */ | ||
3335 | STATIC void | ||
3336 | xfs_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( | |||
3796 | int /* error code */ | 3813 | int /* error code */ |
3797 | xfs_bmap_add_attrfork( | 3814 | xfs_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); |
6132 | error_norelse: | 6172 | error_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 | */ | ||
6330 | int | ||
6331 | xfs_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 | } |