Skip to content

Commit

Permalink
[XFS] use minleft when allocating in xfs_bmbt_split()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Lachlan McIlroy authored and Niv Sardi committed Jul 28, 2008
1 parent e182f57 commit 4ddd8bb
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
15 changes: 14 additions & 1 deletion fs/xfs/xfs_bmap_btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions fs/xfs/xfs_iomap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 4ddd8bb

Please sign in to comment.