|
@@ -763,8 +763,8 @@ xfs_bmap_extents_to_btree(
|
|
|
args.type = XFS_ALLOCTYPE_START_BNO;
|
|
|
args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
|
|
|
} else if (dfops->dop_low) {
|
|
|
-try_another_ag:
|
|
|
args.type = XFS_ALLOCTYPE_START_BNO;
|
|
|
+try_another_ag:
|
|
|
args.fsbno = *firstblock;
|
|
|
} else {
|
|
|
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
|
@@ -790,13 +790,17 @@ try_another_ag:
|
|
|
if (xfs_sb_version_hasreflink(&cur->bc_mp->m_sb) &&
|
|
|
args.fsbno == NULLFSBLOCK &&
|
|
|
args.type == XFS_ALLOCTYPE_NEAR_BNO) {
|
|
|
- dfops->dop_low = true;
|
|
|
+ args.type = XFS_ALLOCTYPE_FIRST_AG;
|
|
|
goto try_another_ag;
|
|
|
}
|
|
|
+ if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) {
|
|
|
+ xfs_iroot_realloc(ip, -1, whichfork);
|
|
|
+ xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
|
|
|
+ return -ENOSPC;
|
|
|
+ }
|
|
|
/*
|
|
|
* Allocation can't fail, the space was reserved.
|
|
|
*/
|
|
|
- ASSERT(args.fsbno != NULLFSBLOCK);
|
|
|
ASSERT(*firstblock == NULLFSBLOCK ||
|
|
|
args.agno >= XFS_FSB_TO_AGNO(mp, *firstblock));
|
|
|
*firstblock = cur->bc_private.b.firstblock = args.fsbno;
|
|
@@ -4150,6 +4154,19 @@ xfs_bmapi_read(
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Add a delayed allocation extent to an inode. Blocks are reserved from the
|
|
|
+ * global pool and the extent inserted into the inode in-core extent tree.
|
|
|
+ *
|
|
|
+ * On entry, got refers to the first extent beyond the offset of the extent to
|
|
|
+ * allocate or eof is specified if no such extent exists. On return, got refers
|
|
|
+ * to the extent record that was inserted to the inode fork.
|
|
|
+ *
|
|
|
+ * Note that the allocated extent may have been merged with contiguous extents
|
|
|
+ * during insertion into the inode fork. Thus, got does not reflect the current
|
|
|
+ * state of the inode fork on return. If necessary, the caller can use lastx to
|
|
|
+ * look up the updated record in the inode fork.
|
|
|
+ */
|
|
|
int
|
|
|
xfs_bmapi_reserve_delalloc(
|
|
|
struct xfs_inode *ip,
|
|
@@ -4236,13 +4253,8 @@ xfs_bmapi_reserve_delalloc(
|
|
|
got->br_startblock = nullstartblock(indlen);
|
|
|
got->br_blockcount = alen;
|
|
|
got->br_state = XFS_EXT_NORM;
|
|
|
- xfs_bmap_add_extent_hole_delay(ip, whichfork, lastx, got);
|
|
|
|
|
|
- /*
|
|
|
- * Update our extent pointer, given that xfs_bmap_add_extent_hole_delay
|
|
|
- * might have merged it into one of the neighbouring ones.
|
|
|
- */
|
|
|
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), got);
|
|
|
+ xfs_bmap_add_extent_hole_delay(ip, whichfork, lastx, got);
|
|
|
|
|
|
/*
|
|
|
* Tag the inode if blocks were preallocated. Note that COW fork
|
|
@@ -4254,10 +4266,6 @@ xfs_bmapi_reserve_delalloc(
|
|
|
if (whichfork == XFS_COW_FORK && (prealloc || aoff < off || alen > len))
|
|
|
xfs_inode_set_cowblocks_tag(ip);
|
|
|
|
|
|
- ASSERT(got->br_startoff <= aoff);
|
|
|
- ASSERT(got->br_startoff + got->br_blockcount >= aoff + alen);
|
|
|
- ASSERT(isnullstartblock(got->br_startblock));
|
|
|
- ASSERT(got->br_state == XFS_EXT_NORM);
|
|
|
return 0;
|
|
|
|
|
|
out_unreserve_blocks:
|