aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@sgi.com>2008-06-26 23:32:53 -0400
committerNiv Sardi <xaiki@debian.org>2008-07-28 02:59:10 -0400
commit4ddd8bb1d25f9cbb345e1f64a56c0f641a787ede (patch)
tree297e8fa754cbd910450ff76a9058a2ac6cd07b39 /fs/xfs
parente182f57ac019b034b40d16f3c6d8e86826aecd56 (diff)
[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>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_bmap_btree.c15
-rw-r--r--fs/xfs/xfs_iomap.c10
2 files changed, 24 insertions, 1 deletions
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 4aa2f11ba563..3fc09cd8d517 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -1493,12 +1493,25 @@ xfs_bmbt_split(
1493 left = XFS_BUF_TO_BMBT_BLOCK(lbp); 1493 left = XFS_BUF_TO_BMBT_BLOCK(lbp);
1494 args.fsbno = cur->bc_private.b.firstblock; 1494 args.fsbno = cur->bc_private.b.firstblock;
1495 args.firstblock = args.fsbno; 1495 args.firstblock = args.fsbno;
1496 args.minleft = 0;
1496 if (args.fsbno == NULLFSBLOCK) { 1497 if (args.fsbno == NULLFSBLOCK) {
1497 args.fsbno = lbno; 1498 args.fsbno = lbno;
1498 args.type = XFS_ALLOCTYPE_START_BNO; 1499 args.type = XFS_ALLOCTYPE_START_BNO;
1500 /*
1501 * Make sure there is sufficient room left in the AG to
1502 * complete a full tree split for an extent insert. If
1503 * we are converting the middle part of an extent then
1504 * we may need space for two tree splits.
1505 *
1506 * We are relying on the caller to make the correct block
1507 * reservation for this operation to succeed. If the
1508 * reservation amount is insufficient then we may fail a
1509 * block allocation here and corrupt the filesystem.
1510 */
1511 args.minleft = xfs_trans_get_block_res(args.tp);
1499 } else 1512 } else
1500 args.type = XFS_ALLOCTYPE_NEAR_BNO; 1513 args.type = XFS_ALLOCTYPE_NEAR_BNO;
1501 args.mod = args.minleft = args.alignment = args.total = args.isfl = 1514 args.mod = args.alignment = args.total = args.isfl =
1502 args.userdata = args.minalignslop = 0; 1515 args.userdata = args.minalignslop = 0;
1503 args.minlen = args.maxlen = args.prod = 1; 1516 args.minlen = args.maxlen = args.prod = 1;
1504 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; 1517 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 7edcde691d1a..67f22b2b44b3 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -889,6 +889,16 @@ xfs_iomap_write_unwritten(
889 count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); 889 count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
890 count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb); 890 count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb);
891 891
892 /*
893 * Reserve enough blocks in this transaction for two complete extent
894 * btree splits. We may be converting the middle part of an unwritten
895 * extent and in this case we will insert two new extents in the btree
896 * each of which could cause a full split.
897 *
898 * This reservation amount will be used in the first call to
899 * xfs_bmbt_split() to select an AG with enough space to satisfy the
900 * rest of the operation.
901 */
892 resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; 902 resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
893 903
894 do { 904 do {