[XFS] use minleft when allocating in xfs_bmbt_split()
The bmap btree split code relies on a previous data extent allocation (from xfs_bmap_btalloc()) to find an AG that has sufficient space to perform a full btree split, when inserting the extent. When converting unwritten extents we don't allocate a data extent so a btree split will be the first allocation. In this case we need to set minleft so the allocator will pick an AG that has space to complete the split(s). SGI-PV: 983338 SGI-Modid: xfs-linux-melb:xfs-kern:31357a Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: David Chinner <dgc@sgi.com>
This commit is contained in:
parent
e182f57ac0
commit
4ddd8bb1d2
|
@ -1493,12 +1493,25 @@ xfs_bmbt_split(
|
|||
left = XFS_BUF_TO_BMBT_BLOCK(lbp);
|
||||
args.fsbno = cur->bc_private.b.firstblock;
|
||||
args.firstblock = args.fsbno;
|
||||
args.minleft = 0;
|
||||
if (args.fsbno == NULLFSBLOCK) {
|
||||
args.fsbno = lbno;
|
||||
args.type = XFS_ALLOCTYPE_START_BNO;
|
||||
/*
|
||||
* Make sure there is sufficient room left in the AG to
|
||||
* complete a full tree split for an extent insert. If
|
||||
* we are converting the middle part of an extent then
|
||||
* we may need space for two tree splits.
|
||||
*
|
||||
* We are relying on the caller to make the correct block
|
||||
* reservation for this operation to succeed. If the
|
||||
* reservation amount is insufficient then we may fail a
|
||||
* block allocation here and corrupt the filesystem.
|
||||
*/
|
||||
args.minleft = xfs_trans_get_block_res(args.tp);
|
||||
} else
|
||||
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
||||
args.mod = args.minleft = args.alignment = args.total = args.isfl =
|
||||
args.mod = args.alignment = args.total = args.isfl =
|
||||
args.userdata = args.minalignslop = 0;
|
||||
args.minlen = args.maxlen = args.prod = 1;
|
||||
args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
|
||||
|
|
|
@ -889,6 +889,16 @@ xfs_iomap_write_unwritten(
|
|||
count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
|
||||
count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb);
|
||||
|
||||
/*
|
||||
* Reserve enough blocks in this transaction for two complete extent
|
||||
* btree splits. We may be converting the middle part of an unwritten
|
||||
* extent and in this case we will insert two new extents in the btree
|
||||
* each of which could cause a full split.
|
||||
*
|
||||
* This reservation amount will be used in the first call to
|
||||
* xfs_bmbt_split() to select an AG with enough space to satisfy the
|
||||
* rest of the operation.
|
||||
*/
|
||||
resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
|
||||
|
||||
do {
|
||||
|
|
Loading…
Reference in New Issue