diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_bmap.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index a9c66d47757a..9bd104f32908 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c | |||
@@ -763,8 +763,8 @@ xfs_bmap_extents_to_btree( | |||
763 | args.type = XFS_ALLOCTYPE_START_BNO; | 763 | args.type = XFS_ALLOCTYPE_START_BNO; |
764 | args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); | 764 | args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); |
765 | } else if (dfops->dop_low) { | 765 | } else if (dfops->dop_low) { |
766 | try_another_ag: | ||
767 | args.type = XFS_ALLOCTYPE_START_BNO; | 766 | args.type = XFS_ALLOCTYPE_START_BNO; |
767 | try_another_ag: | ||
768 | args.fsbno = *firstblock; | 768 | args.fsbno = *firstblock; |
769 | } else { | 769 | } else { |
770 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | 770 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
@@ -790,13 +790,17 @@ try_another_ag: | |||
790 | if (xfs_sb_version_hasreflink(&cur->bc_mp->m_sb) && | 790 | if (xfs_sb_version_hasreflink(&cur->bc_mp->m_sb) && |
791 | args.fsbno == NULLFSBLOCK && | 791 | args.fsbno == NULLFSBLOCK && |
792 | args.type == XFS_ALLOCTYPE_NEAR_BNO) { | 792 | args.type == XFS_ALLOCTYPE_NEAR_BNO) { |
793 | dfops->dop_low = true; | 793 | args.type = XFS_ALLOCTYPE_FIRST_AG; |
794 | goto try_another_ag; | 794 | goto try_another_ag; |
795 | } | 795 | } |
796 | if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { | ||
797 | xfs_iroot_realloc(ip, -1, whichfork); | ||
798 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | ||
799 | return -ENOSPC; | ||
800 | } | ||
796 | /* | 801 | /* |
797 | * Allocation can't fail, the space was reserved. | 802 | * Allocation can't fail, the space was reserved. |
798 | */ | 803 | */ |
799 | ASSERT(args.fsbno != NULLFSBLOCK); | ||
800 | ASSERT(*firstblock == NULLFSBLOCK || | 804 | ASSERT(*firstblock == NULLFSBLOCK || |
801 | args.agno >= XFS_FSB_TO_AGNO(mp, *firstblock)); | 805 | args.agno >= XFS_FSB_TO_AGNO(mp, *firstblock)); |
802 | *firstblock = cur->bc_private.b.firstblock = args.fsbno; | 806 | *firstblock = cur->bc_private.b.firstblock = args.fsbno; |
@@ -4150,6 +4154,19 @@ xfs_bmapi_read( | |||
4150 | return 0; | 4154 | return 0; |
4151 | } | 4155 | } |
4152 | 4156 | ||
4157 | /* | ||
4158 | * Add a delayed allocation extent to an inode. Blocks are reserved from the | ||
4159 | * global pool and the extent inserted into the inode in-core extent tree. | ||
4160 | * | ||
4161 | * On entry, got refers to the first extent beyond the offset of the extent to | ||
4162 | * allocate or eof is specified if no such extent exists. On return, got refers | ||
4163 | * to the extent record that was inserted to the inode fork. | ||
4164 | * | ||
4165 | * Note that the allocated extent may have been merged with contiguous extents | ||
4166 | * during insertion into the inode fork. Thus, got does not reflect the current | ||
4167 | * state of the inode fork on return. If necessary, the caller can use lastx to | ||
4168 | * look up the updated record in the inode fork. | ||
4169 | */ | ||
4153 | int | 4170 | int |
4154 | xfs_bmapi_reserve_delalloc( | 4171 | xfs_bmapi_reserve_delalloc( |
4155 | struct xfs_inode *ip, | 4172 | struct xfs_inode *ip, |
@@ -4236,13 +4253,8 @@ xfs_bmapi_reserve_delalloc( | |||
4236 | got->br_startblock = nullstartblock(indlen); | 4253 | got->br_startblock = nullstartblock(indlen); |
4237 | got->br_blockcount = alen; | 4254 | got->br_blockcount = alen; |
4238 | got->br_state = XFS_EXT_NORM; | 4255 | got->br_state = XFS_EXT_NORM; |
4239 | xfs_bmap_add_extent_hole_delay(ip, whichfork, lastx, got); | ||
4240 | 4256 | ||
4241 | /* | 4257 | xfs_bmap_add_extent_hole_delay(ip, whichfork, lastx, got); |
4242 | * Update our extent pointer, given that xfs_bmap_add_extent_hole_delay | ||
4243 | * might have merged it into one of the neighbouring ones. | ||
4244 | */ | ||
4245 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), got); | ||
4246 | 4258 | ||
4247 | /* | 4259 | /* |
4248 | * Tag the inode if blocks were preallocated. Note that COW fork | 4260 | * Tag the inode if blocks were preallocated. Note that COW fork |
@@ -4254,10 +4266,6 @@ xfs_bmapi_reserve_delalloc( | |||
4254 | if (whichfork == XFS_COW_FORK && (prealloc || aoff < off || alen > len)) | 4266 | if (whichfork == XFS_COW_FORK && (prealloc || aoff < off || alen > len)) |
4255 | xfs_inode_set_cowblocks_tag(ip); | 4267 | xfs_inode_set_cowblocks_tag(ip); |
4256 | 4268 | ||
4257 | ASSERT(got->br_startoff <= aoff); | ||
4258 | ASSERT(got->br_startoff + got->br_blockcount >= aoff + alen); | ||
4259 | ASSERT(isnullstartblock(got->br_startblock)); | ||
4260 | ASSERT(got->br_state == XFS_EXT_NORM); | ||
4261 | return 0; | 4269 | return 0; |
4262 | 4270 | ||
4263 | out_unreserve_blocks: | 4271 | out_unreserve_blocks: |